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,
), ),
actions: <Widget>[ ),
CupertinoDialogAction( const SizedBox(height: 16),
child: Text('Update'.tr), 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 { onPressed: () async {
if (await canLaunchUrl(Uri.parse(storeUrl))) { if (await canLaunchUrl(Uri.parse(storeUrl))) {
await launchUrl(Uri.parse(storeUrl)); await launchUrl(Uri.parse(storeUrl));
} else {
print('Could not launch $storeUrl');
} }
if (context.mounted) Navigator.pop(context);
Navigator.of(context).pop();
}, },
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),
), ),
CupertinoDialogAction(
child: Text('Cancel'.tr),
onPressed: () async {
Navigator.of(context).pop();
},
), ),
], ],
),
],
),
),
),
);
},
transitionBuilder: (_, animation, __, child) {
return ScaleTransition(
scale: CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic, // More natural curve
),
child: child,
); );
}, },
); );

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 {
try {
isLoading = true; isLoading = true;
update();
LatLngBounds bounds = calculateBounds( LatLngBounds bounds = calculateBounds(
Get.find<LocationController>().myLocation!.latitude, Get.find<LocationController>().myLocation!.latitude,
Get.find<LocationController>().myLocation!.longitude, Get.find<LocationController>().myLocation!.longitude,
4000); 4000);
var payload = { var payload = {
// "carType": box.read(BoxName.carTypeOfDriver).toString(),
'southwestLat': bounds.southwest.latitude.toString(), 'southwestLat': bounds.southwest.latitude.toString(),
'southwestLon': bounds.southwest.longitude.toString(), 'southwestLon': bounds.southwest.longitude.toString(),
'northeastLat': bounds.northeast.latitude.toString(), 'northeastLat': bounds.northeast.latitude.toString(),
'northeastLon': bounds.northeast.longitude.toString(), 'northeastLon': bounds.northeast.longitude.toString(),
}; };
Log.print('payload: ${payload}');
var res = await CRUD().get(link: AppLink.getRideWaiting, payload: payload); var res =
Log.print('res: ${res}'); await CRUD().get(link: AppLink.getRideWaiting, payload: payload);
if (res != 'failure') { if (res != 'failure') {
rideAvailableMap = jsonDecode(res); rideAvailableMap = jsonDecode(res);
isLoading = false; isLoading = false;
update(); update();
} else { } else {
MyDialog().getDialog("No Rides Available".tr, '', () { 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();
Get.back(); Get.back();
}); },
child: Text('OK'.tr),
),
],
),
barrierDismissible: true,
transitionCurve: Curves.easeOutBack,
transitionDuration: const Duration(milliseconds: 200),
);
}
} catch (e) {
isLoading = false;
update();
Get.dialog(
CupertinoAlertDialog(
title: const Icon(
CupertinoIcons.exclamationmark_triangle_fill,
color: CupertinoColors.systemRed,
size: 44,
),
content: Text(
"Error fetching rides. Please try again.".tr,
style: const TextStyle(fontSize: 14),
),
actions: [
CupertinoDialogAction(
onPressed: () => Get.back(),
child: Text('OK'.tr),
),
],
),
);
} }
} }

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,
@@ -27,33 +28,120 @@ ThemeData themeEnglish = ThemeData(
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: SingleChildScrollView(
child: Center(
child: Obx(() { child: Obx(() {
// Observe changes in userRating; when updated, rebuild the UI accordingly
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding:
child: ListView( const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
// mainAxisAlignment: child: Column(
// MainAxisAlignment.center, // Center content vertically crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
// App logo or visual
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(16),
child: Image.asset('assets/images/logo.gif')), child: Image.asset(
const SizedBox(height: 10), 'assets/images/logo.gif',
// Text prompt asking the user to rate the app, with localization support height: 120,
Text("How would you rate our app?".tr),
const SizedBox(height: 10), // Vertical spacing between elements
MyTextForm(
controller: ratingController.comment,
label: 'write comment here'.tr,
hint: 'write comment here'.tr,
type: TextInputType.name,
), ),
// Build and display the row of rating stars ),
const SizedBox(height: 20),
// Rating Prompt
Text(
"How would you rate our app?".tr,
textAlign: TextAlign.center,
style: CupertinoTheme.of(context)
.textTheme
.navTitleTextStyle
.copyWith(fontSize: 18, fontWeight: FontWeight.w600),
),
const SizedBox(height: 20),
// Comment Box
CupertinoTextField(
controller: ratingController.comment,
placeholder: 'Write your comment here'.tr,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border.all(color: CupertinoColors.systemGrey4),
borderRadius: BorderRadius.circular(12),
color: CupertinoColors.white,
),
prefix: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Icon(CupertinoIcons.pencil_ellipsis_rectangle,
color: CupertinoColors.systemGrey),
),
),
const SizedBox(height: 20),
// Star Rating Section
_buildRatingStars(), _buildRatingStars(),
const SizedBox( const SizedBox(height: 30),
height: 20), // Additional spacing before the button
// Button to submit the selected rating // Submit Button
MyElevatedButton( CupertinoButton(
padding: const EdgeInsets.symmetric(
horizontal: 24, vertical: 14),
borderRadius: BorderRadius.circular(12),
color: CupertinoColors.activeGreen,
onPressed: () { onPressed: () {
// Calls submitRating() method in the controller with the current rating value if (ratingController.userRating.value > 0) {
ratingController ratingController
.submitRating(ratingController.userRating.value); .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,
);
}
}, },
// Button text "Submit Rating" with localization support child: Text(
title: "Submit Rating".tr, "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),
title: Text('Language'.tr, style: AppStyle.headTitle2),
subtitle: Text('You can change the language of the app'.tr,
style: AppStyle.subtitle),
trailing: const CupertinoListTileChevron(),
onTap: () => Get.to(const Language()), onTap: () => Get.to(const Language()),
), ),
const Divider( CupertinoListTile(
endIndent: 44, leading: const Icon(CupertinoIcons.flag_fill),
indent: 44, title: Text('Change Country'.tr, style: AppStyle.headTitle2),
), subtitle: Text(
ListTile( 'You can change the Country to get all features'.tr,
leading: const Icon(Icons.place_outlined), style: AppStyle.subtitle),
title: Text( trailing: const CupertinoListTileChevron(),
'Change Country'.tr, onTap: () => Get.to(
style: AppStyle.headTitle2, MyScafolld(
),
subtitle:
Text('You can change the Country to get all features'.tr),
onTap: () => Get.to(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, ),
// App Preferences Section
_buildSectionHeader('App Preferences'.tr),
CupertinoListSection(
margin: EdgeInsets.zero,
children: [
CupertinoListTile(
leading: Icon(
CupertinoIcons.map_pin_ellipse,
color: AppColor.redColor, color: AppColor.redColor,
), ),
title: Text( title: Text('Google Map App'.tr, style: AppStyle.headTitle2),
'Google Map App'.tr,
style: AppStyle.headTitle2,
),
subtitle: Text( subtitle: Text(
'If you want to make Google Map App run directly when you apply order' 'If you want to make Google Map App run directly when you apply order'
.tr), .tr,
trailing: style: AppStyle.subtitle,
GetBuilder<SettingController>(builder: (settingController) { ),
trailing: GetBuilder<SettingController>(
builder: (settingController) {
return CupertinoSwitch( return CupertinoSwitch(
value: settingController.isGoogleMapsEnabled, value: settingController.isGoogleMapsEnabled,
activeColor: AppColor.primaryColor, activeTrackColor: AppColor.primaryColor,
onChanged: (bool value) { onChanged: (bool value) {
settingController.onChangMapApp(); 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,
), ),
CupertinoListTile(
leading: Icon(Icons.vibration),
title: Text('Vibration'.tr, style: AppStyle.headTitle2),
subtitle: Text( subtitle: Text(
"You can change the vibration feedback for all buttons".tr, "You can change the vibration feedback for all buttons".tr,
style: AppStyle.title, style: AppStyle.subtitle,
), ),
trailing: GetBuilder<HomePageController>( trailing: GetBuilder<HomePageController>(
builder: (controller) => CupertinoSwitch( builder: (controller) => CupertinoSwitch(
value: controller.isVibrate, value: controller.isVibrate,
onChanged: controller.changeVibrateOption, onChanged: controller.changeVibrateOption,
activeColor: AppColor.primaryColor, activeTrackColor: AppColor.primaryColor,
)), ),
),
onTap: () => print('3'), 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( // Help & Support Section
endIndent: 44, _buildSectionHeader('Help & Support'.tr),
indent: 44, CupertinoListSection(
margin: EdgeInsets.zero,
children: [
CupertinoListTile(
leading: const Icon(CupertinoIcons.question_circle_fill),
title: Text('Frequently Questions'.tr,
style: AppStyle.headTitle2),
trailing: const CupertinoListTileChevron(),
onTap: () => Get.to(() => const FrequentlyQuestionsPage()),
), ),
ListTile( CupertinoListTile(
leading: const Icon(Icons.account_balance_outlined), leading: const Icon(CupertinoIcons.hand_raised_fill),
title: Text( title:
'About Us'.tr, Text("How to use SEFER".tr, style: AppStyle.headTitle2),
style: AppStyle.headTitle2, trailing: const CupertinoListTileChevron(),
), onTap: () => Get.to(() => const UsingAppPage()),
subtitle: Text(
'You can change the Country to get all features'.tr,
style: AppStyle.title,
), ),
CupertinoListTile(
leading: const Icon(CupertinoIcons.info_circle_fill),
title: Text('About Us'.tr, style: AppStyle.headTitle2),
trailing: const CupertinoListTileChevron(),
onTap: () => Get.to(() => const AboutPage()), onTap: () => Get.to(() => const AboutPage()),
), ),
// ListTile( ],
// leading: const Icon(Icons.account_circle), ),
// title: const Text('Account'), const SizedBox(height: 16),
// 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,19 +394,46 @@ 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(
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: CupertinoColors.white,
borderRadius: BorderRadius.circular(10),
),
child: CupertinoButton(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
onPressed: onTap, onPressed: onTap,
child: Row( child: Row(
children: [ children: [
Icon(icon, color: CupertinoColors.activeBlue), Icon(
const SizedBox(width: 10), icon,
Text(text, style: const TextStyle(color: CupertinoColors.label)), 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(), const Spacer(),
const Icon(CupertinoIcons.right_chevron, Icon(
color: CupertinoColors.systemGrey), 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,84 +466,123 @@ class UserAccountHeader extends StatelessWidget {
builder: (imageController) { builder: (imageController) {
return Stack( return Stack(
children: [ children: [
imageController.isloading Container(
? const CupertinoActivityIndicator()
: Container(
width: 100, width: 100,
height: 100, height: 100,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
image: DecorationImage( border: Border.all(color: Colors.white, width: 3),
fit: BoxFit.cover, boxShadow: [
image: NetworkImage( BoxShadow(
'${AppLink.seferCairoServer}/portrate_captain_image/${box.read(BoxName.driverID)}.jpg', 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,
), ),
), ),
), ),
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), ),
Row( const SizedBox(height: 12),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [ children: [
// const Icon(
// CupertinoIcons.star_fill,
// color: CupertinoColors.systemYellow,
// size: 18,
// ),
// const SizedBox(width: 4),
Text( Text(
Get.find<HomeCaptainController>().rating.toString(), Get.find<HomeCaptainController>().rating.toString(),
style: const TextStyle( style: const TextStyle(
color: CupertinoColors.systemYellow, fontSize: 16), color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
), ),
const SizedBox(width: 5), ),
// You might want to replace this with a Cupertino-style rating widget const SizedBox(width: 8),
// For now, we'll use text to represent stars RatingBar.builder(
// 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( 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(
borderRadius: BorderRadius.circular(12.0), color:
border: Border.all( CupertinoTheme.of(context).brightness == Brightness.light
color: CupertinoColors.systemGrey2, ? CupertinoColors.systemGrey6
), : CupertinoColors.darkBackgroundGray,
borderRadius:
BorderRadius.circular(15.0), // More rounded corners
), ),
child: Text( child: Text(
'If you need any help or have questions, this is the right place to do that. You are welcome!' 'If you need any help or have questions, this is the right place to do that. You are welcome!'
.tr, .tr,
style: CupertinoTheme.of(context).textTheme.textStyle, style:
CupertinoTheme.of(context).textTheme.textStyle.copyWith(
fontSize: 16, // Slightly larger font size
color: CupertinoColors.label.resolveFrom(
context), // Ensure text color adapts to theme
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
), const SizedBox(height: 20),
Card( CupertinoFormSection.insetGrouped(
elevation: 3, // Using CupertinoFormSection for better styling
color: CupertinoColors.systemGrey6, header: Text('Submit Your Question'.tr),
shape: RoundedRectangleBorder( margin: EdgeInsets.zero,
borderRadius: BorderRadius.circular(12.0), children: [
), GetBuilder<HelpController>(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: GetBuilder<HelpController>(
builder: (helpController) => Form( builder: (helpController) => Form(
key: helpController.formKey, key: helpController.formKey,
child: Column( child: CupertinoTextFormFieldRow(
children: [
CupertinoTextField(
controller: helpController.helpQuestionController, controller: helpController.helpQuestionController,
placeholder: 'Enter your Question here'.tr, placeholder: 'Enter your Question here'.tr,
decoration: BoxDecoration( autovalidateMode: AutovalidateMode.onUserInteraction,
borderRadius: BorderRadius.circular(12), validator: (value) {
border: Border.all( if (value == null || value.isEmpty) {
color: CupertinoColors.systemGrey, return 'Please enter your question'.tr;
}
return null;
},
prefix: const Icon(CupertinoIcons
.question_circle), // Added a prefix icon
), ),
), ),
padding: const EdgeInsets.all(16),
clearButtonMode: OverlayVisibilityMode.editing,
), ),
const SizedBox(height: 20), Padding(
helpController.isLoading padding: const EdgeInsets.symmetric(
horizontal: 16.0, vertical: 10.0),
child: GetBuilder<HelpController>(
builder: (helpController) => helpController.isLoading
? const CupertinoActivityIndicator() ? const CupertinoActivityIndicator()
: CupertinoButton.filled( : CupertinoButton.filled(
onPressed: () { onPressed: () {
if (helpController.formKey.currentState! if (helpController.formKey.currentState!
.validate()) { .validate()) {
helpController.addHelpQuestion(); helpController.addHelpQuestion();
helpController.helpQuestionController
// Clear the feedback form .clear(); // Clear the text field
helpController.formKey.currentState!
.reset();
} }
}, },
child: Text('Submit Question'.tr), child: Text('Submit Question'.tr),
), ),
),
),
], ],
), ),
),
),
),
),
const SizedBox(height: 20), 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) {
var list = helpController
.helpQuestionDate['message'][index];
return CupertinoListTile(
title: Text(
list['helpQuestion'],
overflow: TextOverflow.ellipsis,
), ),
borderRadius: BorderRadius.circular(12.0), trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
list['datecreated'],
style: CupertinoTheme.of(context)
.textTheme
.tabLabelTextStyle,
), ),
child: ListView.builder( const Icon(CupertinoIcons.chevron_forward),
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: () { 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(
child: Text(
list['helpQuestion'],
style: CupertinoTheme.of(context)
.textTheme
.textStyle,
overflow: TextOverflow.ellipsis,
),
),
Text(
list['datecreated'],
style: CupertinoTheme.of(context)
.textTheme
.tabLabelTextStyle,
),
],
),
),
),
); );
}, },
)
: [
Center(
child: Text('No questions asked yet.'.tr),
), ),
), ],
), ),
), ),
), ),
@@ -167,3 +168,165 @@ class HelpCaptain extends StatelessWidget {
); );
} }
} }
// class HelpCaptain extends StatelessWidget {
// HelpCaptain({super.key});
// @override
// Widget build(BuildContext context) {
// Get.put(HelpController());
// return CupertinoPageScaffold(
// navigationBar: CupertinoNavigationBar(
// middle: Text('Helping Page'.tr),
// leading: CupertinoButton(
// padding: EdgeInsets.zero,
// child: Icon(CupertinoIcons.back),
// onPressed: () => Navigator.pop(context),
// ),
// ),
// child: SafeArea(
// child: Padding(
// padding: const EdgeInsets.all(16.0),
// child: Column(
// children: [
// Padding(
// padding: const EdgeInsets.symmetric(vertical: 12.0),
// child: Container(
// padding: const EdgeInsets.all(16.0),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(12.0),
// border: Border.all(
// color: CupertinoColors.systemGrey2,
// ),
// ),
// child: Text(
// 'If you need any help or have questions, this is the right place to do that. You are welcome!'
// .tr,
// style: CupertinoTheme.of(context).textTheme.textStyle,
// textAlign: TextAlign.center,
// ),
// ),
// ),
// Card(
// elevation: 3,
// color: CupertinoColors.systemGrey6,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(12.0),
// ),
// child: Padding(
// padding: const EdgeInsets.all(16.0),
// child: GetBuilder<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(
gradient: LinearGradient(
colors: [Colors.white, Colors.grey.shade50],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 1,
blurRadius: 4,
),
],
),
),
title: Row(
children: [
Image.asset('assets/images/logo.png', height: 32),
const SizedBox(width: 8),
Text(
'SEFER'.tr, 'SEFER'.tr,
style: AppStyle.title.copyWith(fontSize: 22), style: AppStyle.title.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
color: AppColor.blueColor,
),
),
],
), ),
actions: [ actions: [
MyCircleContainer( Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: MyCircleContainer(
child: Text( child: Text(
homeCaptainController.countRefuse.toString(), homeCaptainController.countRefuse.toString(),
style: AppStyle.title, 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,
),
], ],
), ),
drawer: CupertinoDrawerCaptain(), 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(), // Add this widget at the bottom of the file
body: Stack( body: Stack(
children: [ children: [
GetBuilder<HomeCaptainController>(builder: (homeCaptainController) { GetBuilder<HomeCaptainController>(builder: (homeCaptainController) {
@@ -419,20 +489,25 @@ 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: GestureDetector(
onLongPress: () {
box.write(BoxName.rideStatus, 'delete');
homeCaptainController.update();
},
child: IconButton( child: IconButton(
onPressed: () { onPressed: () {
box.read(BoxName.rideStatus) == 'Applied' box.read(BoxName.rideStatus) == 'Applied'
? { ? {
Get.to(() => PassengerLocationMapPage(), Get.to(() => PassengerLocationMapPage(),
arguments: arguments: box
box.read(BoxName.rideArguments)), .read(BoxName.rideArguments)),
Get.put(MapDriverController()) Get.put(MapDriverController())
.changeRideToBeginToPassenger() .changeRideToBeginToPassenger()
} }
: { : {
Get.to(() => PassengerLocationMapPage(), Get.to(() => PassengerLocationMapPage(),
arguments: arguments: box
box.read(BoxName.rideArguments)), .read(BoxName.rideArguments)),
Get.put(MapDriverController()) Get.put(MapDriverController())
.startRideFromStartApp() .startRideFromStartApp()
}; };
@@ -444,6 +519,7 @@ class HomeCaptain extends StatelessWidget {
), ),
), ),
), ),
),
) )
: const SizedBox() : const SizedBox()
], ],
@@ -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,9 +6,113 @@ 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
@@ -17,82 +121,138 @@ class MaintainCenterPage extends StatelessWidget {
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( ),
mainAxisAlignment: MainAxisAlignment.spaceAround, const SizedBox(height: 20),
// Trip Count Section in a Card
Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
MyElevatedButton( Expanded(
child: MyElevatedButton(
title: "Show My Trip Count".tr, title: "Show My Trip Count".tr,
onPressed: () async { onPressed: () async {
maintainCenterController.getTripCountByCaptain(); controller.getTripCountByCaptain();
}), },
),
),
const SizedBox(width: 16),
_buildPriceAvatar( _buildPriceAvatar(
maintainCenterController.tripCount['count'] == null controller.tripCount['count'] == null
? '0' ? '0'
: maintainCenterController.tripCount['count'] : controller.tripCount['count'].toString(),
.toString()) ),
], ],
), ),
const SizedBox(
height: 10,
), ),
Container( ),
decoration: AppStyle.boxDecoration, const SizedBox(height: 20),
// Maintenance Offer Information in a Card
Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding( child: Padding(
padding: const EdgeInsets.all(14), padding: const EdgeInsets.all(16.0),
child: Text( 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." "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, .tr,
style: AppStyle.title, style: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(
color: Colors.grey[800],
height: 1.5,
),
),
],
), ),
), ),
), ),
const SizedBox( const SizedBox(height: 20),
height: 10,
), // Show Maintenance Center Button
MyElevatedButton( 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

@@ -19,141 +19,87 @@ GetBuilder<MapDriverController> driverEndRideBar() {
top: 5, top: 5,
right: 5, right: 5,
child: Container( child: Container(
decoration: AppStyle.boxDecoration1, decoration: AppStyle.boxDecoration1.copyWith(
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 10,
offset: Offset(0, 5),
),
],
),
padding: const EdgeInsets.all(10),
height: mapDriverController.remainingTimeTimerRideBegin < 60 height: mapDriverController.remainingTimeTimerRideBegin < 60
? mapDriverController.driverEndPage = 190 ? mapDriverController.driverEndPage = 190
: mapDriverController.carType == 'Mishwar Vip' : mapDriverController.carType == 'Mishwar Vip'
? 120 ? 120
: 170, : 170,
// width: 240,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
mapDriverController.carType != 'Mishwar Vip' if (mapDriverController.carType != 'Mishwar Vip')
? Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
Column( _buildInfoColumn(
children: [ icon: Icons.social_distance,
const Icon(Icons.social_distance), text: '${mapDriverController.distance} ${'KM'.tr}',
Text(
'${mapDriverController.distance} ${'KM'.tr}',
style: AppStyle.title,
), ),
], _buildInfoColumn(
), icon: Icons.timelapse,
Column( text: mapDriverController.hours > 1
children: [ ? '${mapDriverController.hours} ${'H and'.tr} ${mapDriverController.minutes} m'
const Icon(Icons.timelapse),
Text(
mapDriverController.hours > 1
? '${'${mapDriverController.hours}${' H and'.tr}'} ${mapDriverController.minutes} m'
: '${mapDriverController.minutes} ${'m'.tr}', : '${mapDriverController.minutes} ${'m'.tr}',
style: AppStyle.title),
],
), ),
Column( _buildInfoColumn(
children: [ icon: Icons.money_sharp,
const Icon(Icons.money_sharp), text:
Text(
'${mapDriverController.paymentAmount} ${'\$'.tr}', '${mapDriverController.paymentAmount} ${'\$'.tr}',
style: AppStyle.title),
],
), ),
], ],
) ),
: const SizedBox(), if (mapDriverController.carType != 'Speed' &&
mapDriverController.carType != 'Speed' &&
mapDriverController.carType != 'Awfar Car' && mapDriverController.carType != 'Awfar Car' &&
mapDriverController.carType != 'Scooter' 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(
icon: Icons.location_on,
text:
'${mapDriverController.recentDistanceToDash.toStringAsFixed(0)} ${'KM'.tr}',
),
_buildInfoBox(
icon: Icons.attach_money,
text: mapDriverController.price.toStringAsFixed(2),
),
],
),
_builtTimerAndCarType(),
Container(
width: Get.width * 0.8,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: AppColor.redColor.withOpacity(0.3),
blurRadius: 8,
offset: Offset(0, 4),
),
],
),
child: SlideAction(
height: 50,
borderRadius: 15,
elevation: 4,
text: 'Slide to End Trip'.tr,
textStyle: AppStyle.title.copyWith(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
@@ -161,67 +107,155 @@ GetBuilder<MapDriverController> driverEndRideBar() {
outerColor: AppColor.redColor, outerColor: AppColor.redColor,
innerColor: Colors.white, innerColor: Colors.white,
sliderButtonIcon: const Icon( sliderButtonIcon: const Icon(
Icons.arrow_forward, Icons.arrow_forward_ios,
color: AppColor.redColor, color: AppColor.redColor,
size: 24,
), ),
sliderRotate: false,
onSubmit: () { onSubmit: () {
HapticFeedback.mediumImpact();
mapDriverController.finishRideFromDriver(); mapDriverController.finishRideFromDriver();
}, },
), ),
// MyElevatedButton( )
// title: 'End Ride'.tr, ],
// onPressed: () { ),
// mapDriverController.finishRideFromDriver(); ),
// }, )
// kolor: AppColor.redColor, : const SizedBox(),
// ), );
// : 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( Container(
decoration: AppStyle.boxDecoration1, 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( child: Text(
mapDriverController.carType, mapDriverController.carType,
style: AppStyle.title, style: AppStyle.title,
), ),
)
],
), ),
mapDriverController.carType != 'Comfort' && if (mapDriverController.carType != 'Comfort' &&
mapDriverController.carType != 'Mishwar Vip' && mapDriverController.carType != 'Mishwar Vip' &&
mapDriverController.carType != 'Lady' mapDriverController.carType != 'Lady')
? Stack( Container(
children: [ width: Get.width * 0.6,
SizedBox( decoration: BoxDecoration(
width: Get.width * .9, borderRadius: BorderRadius.circular(12),
child: Center( gradient: LinearGradient(
child: LinearProgressIndicator( colors: [
backgroundColor: AppColor.greyColor, mapDriverController.remainingTimeTimerRideBegin < 60
color: mapDriverController ? AppColor.redColor.withOpacity(0.8)
.remainingTimeTimerRideBegin < : AppColor.greenColor.withOpacity(0.8),
60 mapDriverController.remainingTimeTimerRideBegin < 60
? AppColor.redColor ? AppColor.redColor
: AppColor.greenColor, : AppColor.greenColor,
minHeight: 25, ],
borderRadius: BorderRadius.circular(6), begin: Alignment.centerLeft,
value: mapDriverController end: Alignment.centerRight,
.progressTimerRideBegin
.toDouble(),
), ),
boxShadow: [
BoxShadow(
color: (mapDriverController.remainingTimeTimerRideBegin < 60
? AppColor.redColor
: AppColor.greenColor)
.withOpacity(0.3),
blurRadius: 8,
offset: Offset(0, 4),
), ),
],
),
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( 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( child: Text(
mapDriverController mapDriverController.stringRemainingTimeRideBegin,
.stringRemainingTimeRideBegin, ),
),
),
],
),
),
),
],
);
}
}
Widget _buildInfoColumn({required IconData icon, required String text}) {
return Column(
children: [
Icon(icon),
Text(
text,
style: AppStyle.title, style: AppStyle.title,
), ),
)
], ],
) );
: const SizedBox(), }
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,
),
], ],
), ),
)) );
: const SizedBox());
} }
GetBuilder<MapDriverController> speedCircle() { GetBuilder<MapDriverController> speedCircle() {

View File

@@ -453,8 +453,11 @@ class PassengerInfoWindow extends StatelessWidget {
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(
middle: Text('Choose Language'.tr),
border: null,
),
child: SafeArea(
child: GetBuilder<LocaleController>(
builder: (controller) => Center( builder: (controller) => Center(
child: Container( child: Padding(
padding: const EdgeInsets.all(15), padding: const EdgeInsets.all(16),
child: ListView( child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
Text( _buildHeader(),
"Choose Language".tr,
style: Theme.of(context).textTheme.headlineLarge,
),
const SizedBox(height: 20), const SizedBox(height: 20),
MyElevatedButton( Expanded(
title: 'العربية', child: ListView(
onPressed: () async { physics: const BouncingScrollPhysics(),
await controller.changeLang("ar"); children: [
Get.defaultDialog( _buildLanguageButton(
title: 'You should restart app to change language'.tr, 'العربية', 'ar', controller, context),
titleStyle: AppStyle.title, _buildLanguageButton(
middleText: '', 'English', 'en', controller, context),
confirm: MyElevatedButton( _buildLanguageButton(
title: 'Ok'.tr, 'Türkçe', 'tr', controller, context),
onPressed: () { _buildLanguageButton(
Get.offAll(() => HomeCaptain()); '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),
],
), ),
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 (vibrate == true) {
if (Platform.isIOS) { if (Platform.isIOS) {
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
} else { } else if (Platform.isAndroid) {
Vibration.vibrate(duration: 100); await Vibration.vibrate(duration: vibrateDuration);
// Vibrate.vibrateWithPauses(pauses); } 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,37 +1,132 @@
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: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.scale(
scale: _scaleAnimation.value,
child: Container( child: Container(
width: 110, width: widget.size,
height: 110, height: widget.size,
decoration: BoxDecoration( decoration: BoxDecoration(
color: backgroundColor, color: widget.backgroundColor,
shape: BoxShape.circle, shape: BoxShape.circle,
), boxShadow: [
child: Stack( BoxShadow(
children: [ color: widget.progressColor.withAlpha(30),
const Center(child: CircularProgressIndicator()), blurRadius: 12,
Column( spreadRadius: 2,
children: [
Align(
alignment: Alignment.center,
child: Image.asset('assets/images/logo.gif'),
), ),
], ],
), ),
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,
tween: Tween(begin: 0.0, end: 1.0),
builder: (context, value, child) {
return Transform.scale(
scale: 0.95 + (0.05 * value),
child: Opacity(opacity: value, child: child),
);
},
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: DialogConfig.blurStrength,
sigmaY: DialogConfig.blurStrength,
),
child: Theme(
data: ThemeData.light().copyWith(
dialogBackgroundColor: CupertinoColors.systemBackground,
),
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: Text( title: Column(
children: [
Text(
title, title,
style: AppStyle.title.copyWith( style: AppStyle.title.copyWith(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w700,
letterSpacing: -0.5,
color: AppColor.primaryColor,
), ),
), ),
const SizedBox(height: 8),
],
),
content: Column( content: Column(
children: [ children: [
CupertinoButton( CupertinoButton(
padding: const EdgeInsets.all(8),
onPressed: () async { onPressed: () async {
HapticFeedback.selectionClick();
await textToSpeechController.speakText(title); await textToSpeechController.speakText(title);
await textToSpeechController.speakText(midTitle!); await textToSpeechController.speakText(midTitle!);
}, },
child: const Icon(CupertinoIcons.speaker_2, child: Container(
color: AppColor.primaryColor), 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( Text(
midTitle!, midTitle!,
style: AppStyle.title.copyWith(fontSize: 16), style: AppStyle.title.copyWith(
fontSize: 16,
height: 1.3,
color: Colors.black87,
),
textAlign: TextAlign.center,
), ),
], ],
), ),
actions: [ actions: [
CupertinoDialogAction( CupertinoDialogAction(
child: const Text('Cancel',
style: TextStyle(color: AppColor.redColor)),
onPressed: () { onPressed: () {
HapticFeedback.lightImpact();
Get.back(); Get.back();
}, },
child: Text(
'Cancel',
style: TextStyle(
color: AppColor.redColor,
fontWeight: FontWeight.w600,
fontSize: 17,
),
),
), ),
CupertinoDialogAction( CupertinoDialogAction(
onPressed: onPressed, onPressed: () {
child: Text('OK'.tr, HapticFeedback.mediumImpact();
style: const TextStyle(color: AppColor.greenColor)), onPressed();
},
child: Text(
'OK'.tr,
style: TextStyle(
color: AppColor.greenColor,
fontWeight: FontWeight.w600,
fontSize: 17,
),
),
), ),
], ],
), ),
), ),
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,
tween: Tween(begin: 0.0, end: 1.0),
builder: (context, value, child) {
return Transform.scale(
scale: 0.95 + (0.05 * value),
child: Opacity(opacity: value, child: child),
);
},
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: DialogConfig.blurStrength,
sigmaY: DialogConfig.blurStrength,
),
child: Theme(
data: ThemeData.light().copyWith(
dialogBackgroundColor: CupertinoColors.systemBackground,
),
child: CupertinoAlertDialog( child: CupertinoAlertDialog(
title: Text( title: Column(
children: [
Text(
title, title,
style: AppStyle.title.copyWith( style: AppStyle.title.copyWith(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w700,
letterSpacing: -0.5,
color: AppColor.primaryColor,
), ),
), ),
const SizedBox(height: 8),
],
),
content: Column( content: Column(
children: [ children: [
CupertinoButton( CupertinoButton(
padding: const EdgeInsets.all(8),
onPressed: () async { onPressed: () async {
HapticFeedback.selectionClick();
await textToSpeechController.speakText(title); await textToSpeechController.speakText(title);
}, },
child: const Icon(CupertinoIcons.headphones, child: Container(
color: AppColor.primaryColor), padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color:
AppColor.primaryColor.withAlpha(26), // 0.1 opacity
borderRadius: BorderRadius.circular(8),
), ),
content! child: Icon(
CupertinoIcons.headphones,
color: AppColor.primaryColor,
size: 24,
),
),
),
const SizedBox(height: 12),
content!,
], ],
), ),
actions: [ actions: [
CupertinoDialogAction( CupertinoDialogAction(
child: const Text('Cancel',
style: TextStyle(color: AppColor.redColor)),
onPressed: () { onPressed: () {
HapticFeedback.lightImpact();
Get.back(); Get.back();
}, },
child: Text(
'Cancel',
style: TextStyle(
color: AppColor.redColor,
fontWeight: FontWeight.w600,
fontSize: 17,
),
),
), ),
CupertinoDialogAction( CupertinoDialogAction(
onPressed: onPressed, onPressed: () {
child: Text('OK'.tr, HapticFeedback.mediumImpact();
style: const TextStyle(color: AppColor.greenColor)), onPressed();
},
child: Text(
'OK'.tr,
style: TextStyle(
color: AppColor.greenColor,
fontWeight: FontWeight.w600,
fontSize: 17,
),
),
), ),
], ],
), ),
), ),
barrierDismissible: false, ),
),
barrierDismissible: true,
barrierColor: Colors.black.withAlpha(102), // 0.4 opacity
); );
} }
} }