This commit is contained in:
Hamza-Ayed
2024-08-27 10:49:43 +03:00
parent 2bc71355c3
commit d23020188e
48 changed files with 1872 additions and 432 deletions

View File

@@ -0,0 +1,101 @@
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/functions/launch.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import '../../../controller/functions/tts.dart';
import '../../../controller/home/captin/contact_us_controller.dart';
class ContactUsPage extends StatelessWidget {
ContactUsPage({super.key});
@override
Widget build(BuildContext context) {
Get.put(ContactUsController());
return GetBuilder<ContactUsController>(builder: (controller) {
return MyScafolld(
title: "Contact Us".tr,
body: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
decoration: AppStyle.boxDecoration1,
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image.asset('assets/images/logo.gif')),
IconButton(
onPressed: () async {
Get.put(TextToSpeechController()).speakText(
'SEFER is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.'
.tr);
},
icon: const Icon(Icons.headphones),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'SEFER is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.'
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
),
],
),
),
const SizedBox(
height: 30,
),
Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"You can contact us during working hours from 12:00 - 19:00."
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
),
),
InkWell(
onTap: () => controller.showContactDialog(context),
child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
Icons.phone,
color: AppColor.blueColor,
),
Icon(
FontAwesome.whatsapp,
color: AppColor.greenColor,
),
Icon(
Icons.email,
color: AppColor.redColor,
),
],
),
),
const SizedBox(
height: 30,
)
],
),
)
],
isleading: true);
});
}
}

View File

@@ -1,11 +1,15 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/my_textField.dart';
import 'package:flutter/material.dart';
import 'package:flutter_contacts/contact.dart';
import 'package:get/get.dart';
import '../../../controller/auth/captin/invit_controller.dart';
import '../../../print.dart';
class InviteDriverScreen extends StatelessWidget {
final InviteController controller = Get.put(InviteController());
@@ -36,9 +40,43 @@ class InviteDriverScreen extends StatelessWidget {
),
),
IconButton(
icon: Icon(Icons.contacts),
icon: const Icon(Icons.contacts),
onPressed: () async {
await controller.pickContact();
await controller.pickContacts();
if (controller.contacts.isNotEmpty) {
if (box.read(BoxName.IsSavedPhones) == null) {
controller.savePhoneToServer();
box.write(BoxName.IsSavedPhones, true);
}
Get.defaultDialog(
title: 'Choose from contact'.tr,
content: Column(
children: [
SizedBox(
height: 300,
child: ListView.builder(
itemCount: controller.contactMaps.length,
itemBuilder: (context, index) {
final contact = controller.contactMaps[index];
return InkWell(
onTap: () {
controller.selectPhone(
contact['phones'].toString());
},
child: ListTile(
title: Text(contact['name'].toString()),
subtitle: Text(
controller.formatPhoneNumber(
contact['phones'][0].toString())),
),
);
},
),
),
],
),
);
}
},
),
],

View File

@@ -407,7 +407,7 @@ class LoginCaptin extends StatelessWidget {
style: AppStyle.title.copyWith(color: AppColor.greenColor),
),
MyElevatedButton(
title: 'Grant Location'.tr,
title: "Allow Location Access".tr,
onPressed: () async {
// await Get.put(LocationBackgroundController()); //////
box.write(BoxName.locationPermission, 'true');

View File

@@ -0,0 +1,101 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class AboutPage extends StatelessWidget {
const AboutPage({super.key});
@override
Widget build(BuildContext context) {
return MyScafolld(
title: 'About Us'.tr,
body: [
// Company Logo (consider adding an image asset)
ListView(
children: [
Center(
child: Image.asset(
'assets/images/logo.png', // Replace with your logo image asset path
height: 100.0,
width: 100.0,
),
), // Company Name and Location
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'SEFER LLC\n${box.read(BoxName.countryCode).toString().tr}',
style: AppStyle.headTitle2,
textAlign: TextAlign.center,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'SEFER is a ride-sharing app designed with your safety and affordability in mind. We connect you with reliable drivers in your area, ensuring a convenient and stress-free travel experience.\n\nHere are some of the key features that set us apart:'
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
), // Security Features List
const SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
children: [
Row(
children: [
const Icon(Icons.lock, color: Colors.blue),
const SizedBox(width: 8.0),
Text(
'Most Secure Methods'.tr,
style: AppStyle.title,
),
],
),
const SizedBox(height: 8.0),
Row(
children: [
const Icon(Icons.phone, color: Colors.blue),
const SizedBox(width: 8.0),
Text(
'In-App VOIP Calls'.tr,
style: AppStyle.title,
),
],
),
const SizedBox(height: 8.0),
Row(
children: [
const Icon(Icons.videocam, color: Colors.blue),
const SizedBox(width: 8.0),
Text(
'Recorded Trips for Safety'.tr,
style: AppStyle.title,
),
],
),
],
),
), // Affordability Highlight
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'\nWe also prioritize affordability, offering competitive pricing to make your rides accessible.'
.tr,
style: AppStyle.title,
textAlign: TextAlign.center,
),
),
],
),
// About Us Text
],
isleading: true);
}
}

View File

@@ -0,0 +1,145 @@
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:SEFER/views/widgets/mydialoug.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../constant/style.dart';
class FrequentlyQuestionsPage extends StatelessWidget {
const FrequentlyQuestionsPage({super.key});
@override
Widget build(BuildContext context) {
String selectedPayment = 'cash'; // Replace with your initial selection
bool canCancelRide = false;
return MyScafolld(
title: 'Frequently Questions'.tr,
body: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
// Question 1: How do I request a ride?
ExpansionTile(
title: Text(
'How do I request a ride?'.tr,
style: AppStyle.title,
),
children: [
Text(
'Step-by-step instructions on how to request a ride through the Sefer app.'
.tr,
style: AppStyle.title,
),
],
),
// Question 2: What types of vehicles are available?
ExpansionTile(
title: Text(
'What types of vehicles are available?'.tr,
style: AppStyle.title,
),
children: [
Text(
'Sefer offers a variety of vehicle options to suit your needs, including economy, comfort, and luxury. Choose the option that best fits your budget and passenger count.'
.tr,
style: AppStyle.title,
),
],
),
// Question 3: How can I pay for my ride?
ExpansionTile(
title: Text(
'How can I pay for my ride?'.tr,
style: AppStyle.title,
),
children: [
Text(
'Sefer offers multiple payment methods for your convenience. Choose between cash payment or credit/debit card payment during ride confirmation.'
.tr,
style: AppStyle.title,
),
],
),
// Question 4: Can I cancel my ride? (if applicable)
ExpansionTile(
title: Text(
'Can I cancel my ride?'.tr,
style: AppStyle.title,
),
children: [
Text(
'Yes, you can cancel your ride under certain conditions (e.g., before driver is assigned). See the Sefer cancellation policy for details.'
.tr,
style: AppStyle.title,
),
],
),
// Question 5 & 6: Driver-specific questions
ExpansionTile(
title: Text(
'Driver Registration & Requirements'.tr,
style: AppStyle.title,
),
children: [
Text(
'${'How can I register as a driver?'.tr}\n${'What are the requirements to become a driver?'.tr}',
style: AppStyle.title,
),
InkWell(
onTap: () {
MyDialog().getDialog('title', 'midTitle', () {
; //todo add in this dialog papers for driver
});
},
child: Text(
'Visit our website or contact Sefer support for information on driver registration and requirements.'
.tr,
style: AppStyle.title,
),
),
],
),
// Question 7: How do I communicate with the other party?
ExpansionTile(
title: Text(
'How do I communicate with the other party (passenger/driver)?'
.tr,
style: AppStyle.title,
),
children: [
Text(
'Sefer provides in-app chat functionality to allow you to communicate with your driver or passenger during your ride.'
.tr,
style: AppStyle.title,
),
],
),
// Question 8: What safety measures does Sefer offer?
ExpansionTile(
title: Text(
'What safety measures does Sefer offer?'.tr,
style: AppStyle.title,
),
children: [
Text(
'Sefer prioritizes your safety. We offer features like driver verification, in-app trip tracking, and emergency contact options.'
.tr,
style: AppStyle.title,
),
],
),
],
),
)
],
isleading: true);
}
}

View File

@@ -8,7 +8,11 @@ import 'package:SEFER/constant/style.dart';
import 'package:SEFER/views/lang/languages.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import '../../auth/country_widget.dart';
import '../../../../controller/functions/vibrate.dart';
import '../../../auth/country_widget.dart';
import 'about_us.dart';
import 'frequantly_question.dart';
import 'using_app_page.dart';
class SettingsCaptain extends StatelessWidget {
const SettingsCaptain({super.key});
@@ -16,6 +20,7 @@ class SettingsCaptain extends StatelessWidget {
@override
Widget build(BuildContext context) {
Get.put(SettingController());
Get.put(HomePageController());
return MyScafolld(
title: 'Settings'.tr,
body: [
@@ -67,6 +72,7 @@ class SettingsCaptain extends StatelessWidget {
GetBuilder<SettingController>(builder: (settingController) {
return CupertinoSwitch(
value: settingController.isGoogleMapsEnabled,
activeColor: AppColor.primaryColor,
onChanged: (bool value) {
settingController.onChangMapApp();
},
@@ -77,6 +83,73 @@ class SettingsCaptain extends StatelessWidget {
endIndent: 44,
indent: 44,
),
ListTile(
leading: const Icon(Icons.question_answer),
title: Text(
'Frequently Questions'.tr,
style: AppStyle.headTitle2,
),
subtitle: Text(
'You can change the Country to get all features'.tr,
style: AppStyle.title,
),
onTap: () => Get.to(() => const FrequentlyQuestionsPage()),
),
const Divider(
endIndent: 44,
indent: 44,
),
ListTile(
leading: const Icon(Icons.vibration),
title: Text(
'Vibration'.tr,
style: AppStyle.headTitle2,
),
subtitle: Text(
"You can change the vibration feedback for all buttons".tr,
style: AppStyle.title,
),
trailing: GetBuilder<HomePageController>(
builder: (controller) => CupertinoSwitch(
value: controller.isVibrate,
onChanged: controller.changeVibrateOption,
activeColor: AppColor.primaryColor,
)),
onTap: () => print('3'),
),
const Divider(
endIndent: 44,
indent: 44,
),
ListTile(
leading: const Icon(Icons.help_outline),
title: Text(
"How to use SEFER".tr,
style: AppStyle.headTitle2,
),
subtitle: Text(
''.tr,
style: AppStyle.title,
),
onTap: () => Get.to(() => const UsingAppPage()),
),
const Divider(
endIndent: 44,
indent: 44,
),
ListTile(
leading: const Icon(Icons.account_balance_outlined),
title: Text(
'About Us'.tr,
style: AppStyle.headTitle2,
),
subtitle: Text(
'You can change the Country to get all features'.tr,
style: AppStyle.title,
),
onTap: () => Get.to(() => const AboutPage()),
),
// ListTile(
// leading: const Icon(Icons.account_circle),
// title: const Text('Account'),

View File

@@ -0,0 +1,109 @@
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:SEFER/views/widgets/mydialoug.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class UsingAppPage extends StatelessWidget {
const UsingAppPage({super.key});
@override
Widget build(BuildContext context) {
return MyScafolld(
title: "How to use SEFER".tr,
body: [
SizedBox(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
InkWell(
onTap: () {
MyDialogContent().getDialog(
"What are the order details we provide to you?".tr,
Image.network(
'https://api.sefer.live/sefer/imageForUsingApp/order_page.jpg',
height: 300,
width: 300,
fit: BoxFit.cover,
),
() {});
},
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"What are the order details we provide to you?".tr,
style: AppStyle.title,
),
),
),
),
const SizedBox(
height: 20,
),
InkWell(
onTap: () {
MyDialog().getDialog(
"What are the order details we provide to you?".tr,
'''Sefer Wallet Features:
Transfer money multiple times.
Transfer to anyone.
Make purchases.
Charge your account.
Charge a friend's Sefer account.
Store your money with us and receive it in your bank as a monthly salary.'''
.tr,
() {});
},
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"What is the feature of our wallet?".tr,
style: AppStyle.title,
),
),
),
),
const SizedBox(
height: 20,
),
InkWell(
onTap: () {
MyDialog().getDialog(
"What are the order details we provide to you?".tr,
'''Types of Trips in Sefer:
Comfort: For cars newer than 2017 with air conditioning.
Lady: For girl drivers.
Speed: For fixed salary and endpoints.
Mashwari: For flexible trips where passengers choose the car and driver with prior arrangements.
Raih Gai: For same-day return trips longer than 50km.
'''
.tr,
() {});
},
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"What is Types of Trips in Sefer?".tr,
style: AppStyle.title,
),
),
),
),
],
),
),
)
],
isleading: true,
);
}
}

View File

@@ -2,6 +2,7 @@ import 'package:SEFER/constant/api_key.dart';
import 'package:SEFER/constant/links.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:SEFER/views/auth/captin/contact_us_page.dart';
import 'package:SEFER/views/auth/captin/invite_driver_screen.dart';
import 'package:SEFER/views/notification/available_rides_page.dart';
import 'package:flutter/material.dart';
@@ -13,12 +14,13 @@ import 'package:SEFER/main.dart';
import 'package:SEFER/views/auth/captin/logout_captain.dart';
import 'package:SEFER/views/home/Captin/history/history_captain.dart';
import 'package:SEFER/views/home/Captin/home_captain/help_captain.dart';
import 'package:SEFER/views/home/Captin/settings_captain.dart';
import 'package:SEFER/views/home/Captin/About%20Us/settings_captain.dart';
import 'package:SEFER/views/home/my_wallet/walet_captain.dart';
import 'package:SEFER/views/home/profile/profile_captain.dart';
import 'package:SEFER/views/notification/notification_captain.dart';
import '../../../../controller/functions/upload_image.dart';
import '../maintain_center_page.dart';
class DrawerCaptain extends StatelessWidget {
ImageController imageController = Get.put(ImageController());
@@ -80,6 +82,20 @@ class DrawerCaptain extends StatelessWidget {
Get.to(() => InviteDriverScreen(), transition: Transition.size),
),
_buildDivider(),
_buildDrawerItem(
icon: Icons.car_repair_outlined,
text: "Maintenance Center".tr,
onTap: () =>
Get.to(() => MaintainCenterPage(), transition: Transition.size),
),
_buildDivider(),
_buildDrawerItem(
icon: Icons.contact_mail_rounded,
text: "Contact Us".tr,
onTap: () =>
Get.to(() => ContactUsPage(), transition: Transition.cupertino),
),
_buildDivider(),
_buildDrawerItem(
icon: Icons.settings,
text: 'Settings'.tr,

View File

@@ -1,17 +1,20 @@
import 'dart:io';
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/controller/home/captin/map_driver_controller.dart';
import 'package:SEFER/views/notification/available_rides_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:SEFER/views/home/Captin/home_captain/drawer_captain.dart';
import 'package:SEFER/views/widgets/mycircular.dart';
import 'package:bubble_head/bubble.dart';
import '../../../../constant/colors.dart';
import '../../../../constant/info.dart';
import '../../../../constant/style.dart';
import '../../../../constant/table_names.dart';
import '../../../../controller/functions/location_controller.dart';
import '../../../../controller/functions/overlay_permisssion.dart';
import '../../../../controller/functions/package_info.dart';
@@ -36,7 +39,7 @@ class HomeCaptain extends StatelessWidget {
Get.put(HomeCaptainController());
Get.put(CaptainWalletController());
WidgetsBinding.instance.addPostFrameCallback((_) {
// checkForUpdate(context);
checkForUpdate(context);
getPermissionOverlay();
_showFirstTimeOfferNotification(context);
});
@@ -245,65 +248,107 @@ class HomeCaptain extends StatelessWidget {
// ),
// ),
Positioned(
bottom: Get.height * .3,
bottom: Get.height * .2,
right: 6,
child: AnimatedContainer(
duration: const Duration(microseconds: 200),
width: homeCaptainController.widthMapTypeAndTraffic,
decoration: BoxDecoration(
border: Border.all(color: AppColor.blueColor),
color: AppColor.secondaryColor,
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () {
Get.to(() => AvailableRidesPage());
},
icon: const Icon(
Icons.train_sharp,
size: 29,
color: AppColor.blueColor,
child: Column(
children: [
Platform.isAndroid
? AnimatedContainer(
duration: const Duration(microseconds: 200),
width: homeCaptainController.widthMapTypeAndTraffic,
decoration: BoxDecoration(
border: Border.all(color: AppColor.blueColor),
color: AppColor.secondaryColor,
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () async {
// final Bubble _bubble = Bubble(showCloseButton: false);
// try {
// await _bubble.startBubbleHead(
// sendAppToBackground: false);
// } on PlatformException {
// print('Failed to call startBubbleHead');
// }
Bubble().startBubbleHead(sendAppToBackground: true);
},
icon: Image.asset(
'assets/images/logo1.png',
fit: BoxFit.cover,
width: 35,
height: 35,
),
),
)
: const SizedBox(),
const SizedBox(
height: 5,
),
),
AnimatedContainer(
duration: const Duration(microseconds: 200),
width: homeCaptainController.widthMapTypeAndTraffic,
decoration: BoxDecoration(
border: Border.all(color: AppColor.blueColor),
color: AppColor.secondaryColor,
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () {
Get.to(() => const AvailableRidesPage());
},
icon: const Icon(
Icons.train_sharp,
size: 29,
color: AppColor.blueColor,
),
),
),
const SizedBox(
height: 5,
),
box.read(BoxName.rideStatus) == 'Applied' ||
box.read(BoxName.rideStatus) == 'Begin'
? Positioned(
bottom: Get.height * .2,
right: 6,
child: AnimatedContainer(
duration: const Duration(microseconds: 200),
width: homeCaptainController.widthMapTypeAndTraffic,
decoration: BoxDecoration(
border: Border.all(color: AppColor.blueColor),
color: AppColor.secondaryColor,
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () {
box.read(BoxName.rideStatus) == 'Applied'
? {
Get.to(() => PassengerLocationMapPage(),
arguments:
box.read(BoxName.rideArguments)),
Get.put(MapDriverController())
.changeRideToBeginToPassenger()
}
: {
Get.to(() => PassengerLocationMapPage(),
arguments:
box.read(BoxName.rideArguments)),
Get.put(MapDriverController())
.startRideFromStartApp()
};
},
icon: const Icon(
Icons.rice_bowl,
size: 29,
color: AppColor.blueColor,
),
),
),
)
: const SizedBox()
],
),
),
leftMainMenuCaptainIcons(),
box.read(BoxName.rideStatus) == 'Applied' ||
box.read(BoxName.rideStatus) == 'Begin'
? Positioned(
bottom: Get.height * .2,
right: 6,
child: AnimatedContainer(
duration: const Duration(microseconds: 200),
width: homeCaptainController.widthMapTypeAndTraffic,
decoration: BoxDecoration(
border: Border.all(color: AppColor.blueColor),
color: AppColor.secondaryColor,
borderRadius: BorderRadius.circular(15)),
child: IconButton(
onPressed: () {
box.read(BoxName.rideStatus) == 'Applied'
? {
Get.to(() => PassengerLocationMapPage(),
arguments: box.read(BoxName.rideArguments)),
Get.put(MapDriverController())
.changeRideToBeginToPassenger()
}
: {
Get.to(() => PassengerLocationMapPage(),
arguments: box.read(BoxName.rideArguments)),
Get.put(MapDriverController())
.startRideFromStartApp()
};
},
icon: const Icon(
Icons.rice_bowl,
size: 29,
color: AppColor.blueColor,
),
),
),
)
: const SizedBox()
// callPage(),
// Positioned(

View File

@@ -1,8 +1,9 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/main.dart';
import 'package:SEFER/views/auth/captin/cards/egypt_card_a_i.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:bubble_head/bubble.dart';
import 'package:get/get.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
@@ -185,12 +186,12 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
// "114243034311436865474",
// "113172279072358305645",
// "hamza ayed",
// "c9kqjnLqu08yogitln6B1Y:APA91bHyFJ7E7zv6-HIikwr6FrlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3",
// "rlMbi4Hc8L1STMPE99iPKqK4Gddwv8r9qZOCadsz9qTEJZ6KLEE9ruTJI6N8dKfK4CXez5pme5WIs14-1QGo29s07fQOniZgIlJV5XFL3yqzPRSUmn3",
// "+201023248456",
// "1 min",
// "1 m",
// "false",
// "em3j-v3PQlecGsTKFNU1wc:APA91bFjHq8xHpzeQwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9",
// "QwUMoyUtZ0J3oR6yXKUavrB_gBl9npUZe-qZtax-Raq4QBbdKv0AmtLKm0BfBd6N_592HBv4CVa41ii4122W3hr-BCUKKzJhzZcK8m0YjbWbtpvgJRD8uD_nuMk9",
// "0",
// "238",
// "false",
@@ -240,23 +241,23 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
// } catch (e) {
// print('Error showing overlay: $e');
// }
// // final Bubble _bubble = Bubble(showCloseButton: true);
// // try {
// // await _bubble.startBubbleHead(sendAppToBackground: false);
// // } on PlatformException {
// // print('Failed to call startBubbleHead');
// // }
//
// // Bubble().startBubbleHead(sendAppToBackground: true);
// // }
//
// // Future<void> stopBubbleHead() async {
// // try {
// // await _bubble.stopBubbleHead();
// // } on PlatformException {
// // print('Failed to call stopBubbleHead');
// // }
// // }
// final Bubble _bubble = Bubble(showCloseButton: true);
// try {
// await _bubble.startBubbleHead(sendAppToBackground: false);
// } on PlatformException {
// print('Failed to call startBubbleHead');
// }
// Bubble().startBubbleHead(sendAppToBackground: true);
// }
// Future<void> stopBubbleHead() async {
// try {
// await _bubble.stopBubbleHead();
// } on PlatformException {
// print('Failed to call stopBubbleHead');
// }
// }
//
// // // send data to ovelay
// },
@@ -278,8 +279,7 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
// child: Builder(builder: (context) {
// return IconButton(
// onPressed: () async {
// // Log.print('box: ${box.read(BoxName.rideStatus)}');
// Log.print('box: ${box.read(BoxName.tokenDriver)}');
// Get.to(() => EgyptCardAI());
// },
// icon: const Icon(
// FontAwesome5.closed_captioning,

View File

@@ -0,0 +1,111 @@
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/home/captin/help/maintain_center_controller.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:SEFER/views/widgets/my_scafold.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class MaintainCenterPage extends StatelessWidget {
MaintainCenterPage({super.key});
MaintainCenterController maintainCenterController =
Get.put(MaintainCenterController());
@override
Widget build(BuildContext context) {
return MyScafolld(
title: "Maintenance Center".tr,
body: [
GetBuilder<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,
),
),
),
);
}
}

View File

@@ -23,11 +23,12 @@ class OrderRequestPage extends StatelessWidget {
OrderRequestPage({super.key});
OrderRequestController orderRequestController =
Get.put(OrderRequestController());
// res = orderRequestController.res;
@override
Widget build(BuildContext context) {
//TODO show order from start page from sql or api
final arguments = Get.arguments;
// String res = '';
final myListString = arguments['myListString'];
var myList;
@@ -38,6 +39,20 @@ class OrderRequestPage extends StatelessWidget {
myList = arguments['DriverList'];
}
// Future.delayed(const Duration(milliseconds: 500));
// if (res.toString() == 'Apply' || res.toString() == 'Finished') {
// WidgetsBinding.instance.addPostFrameCallback((_) {
// Get.defaultDialog(
// barrierDismissible: false,
// title: 'This trip is taken'.tr,
// middleText: '',
// confirm: MyElevatedButton(
// title: 'Ok'.tr,
// onPressed: () {
// Get.back();
// }));
// });
// }
// final pointsList = arguments['PolylineJson'];
// final body = arguments['body'];
Duration durationToAdd = Duration(seconds: int.parse(myList[4]));
@@ -507,4 +522,6 @@ class OrderRequestPage extends StatelessWidget {
],
isleading: false);
}
void checkRideStatus() async {}
}

View File

@@ -148,12 +148,16 @@ class CardSeferWalletDriver extends StatelessWidget {
},
child: Container(
width: Get.width * .85,
height: Get.height * .27,
height: Get.height * .2,
decoration: BoxDecoration(
color: AppColor.deepPurpleAccent,
borderRadius: const BorderRadius.all(Radius.circular(12)),
gradient: const LinearGradient(
colors: [AppColor.greyColor, AppColor.writeColor]),
gradient: const LinearGradient(colors: [
AppColor.greyColor,
AppColor.greyColor,
AppColor.secondaryColor,
AppColor.writeColor
]),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,

View File

@@ -19,6 +19,7 @@ import 'package:SEFER/views/widgets/my_textField.dart';
import 'package:SEFER/views/widgets/mycircular.dart';
import '../../../controller/payment/driver_payment_controller.dart';
import '../../../print.dart';
import '../../widgets/my_scafold.dart';
import 'card_wallet_widget.dart';
import 'points_captain.dart';
@@ -120,6 +121,8 @@ class WalletCaptain extends StatelessWidget {
color: AppColor.writeColor)),
child: GestureDetector(
onTap: () {
Log.print(
'captainWalletController.totalAmount: ${captainWalletController.totalAmount}');
Get.snackbar(
icon: InkWell(
onTap: () async {

View File

@@ -35,8 +35,11 @@ class WeeklyPaymentPage extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
controller.weeklyList[0]['totalAmount']
.toString(),
controller.weeklyList.isEmpty
? '0'
: controller.weeklyList[0]
['totalAmount']
.toString(),
style: AppStyle.number,
),
),
@@ -57,66 +60,76 @@ class WeeklyPaymentPage extends StatelessWidget {
horizontal: 10, vertical: 5),
child: SizedBox(
height: Get.height * .75,
child: ListView.builder(
itemCount: controller.weeklyList.length,
itemBuilder: (BuildContext context, int index) {
var list = controller.weeklyList[index];
return Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(4),
child: Column(
children: [
Card(
elevation: 2,
color: list['paymentMethod'] == 'visa'
? AppColor.blueColor
: AppColor.secondaryColor,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
list['paymentMethod'] ==
'Remainder'
? 'Remainder'.tr
: list['paymentMethod'] ==
'fromBudget'
? 'fromBudget'.tr
: list['paymentMethod'],
style: AppStyle.title,
),
),
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Card(
child: Padding(
padding:
const EdgeInsets.all(8.0),
child: Text(
list['amount'],
style: AppStyle.number,
child: controller.weeklyList.isNotEmpty
? ListView.builder(
itemCount: controller.weeklyList.length,
itemBuilder:
(BuildContext context, int index) {
var list = controller.weeklyList[index];
return Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(4),
child: Column(
children: [
Card(
elevation: 2,
color: list['paymentMethod'] ==
'visa'
? AppColor.blueColor
: AppColor.secondaryColor,
child: Padding(
padding:
const EdgeInsets.all(8.0),
child: Text(
list['paymentMethod'] ==
'Remainder'
? 'Remainder'.tr
: list['paymentMethod'] ==
'fromBudget'
? 'fromBudget'.tr
: list[
'paymentMethod'],
style: AppStyle.title,
),
),
),
),
Text(
DateFormat('yyyy-MM-dd hh:mm a')
.format(DateTime.parse(
list['dateUpdated'])),
style: AppStyle.number,
),
],
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Card(
child: Padding(
padding:
const EdgeInsets.all(
8.0),
child: Text(
list['amount'],
style: AppStyle.number,
),
),
),
Text(
DateFormat(
'yyyy-MM-dd hh:mm a')
.format(DateTime.parse(
list[
'dateUpdated'])),
style: AppStyle.number,
),
],
),
],
),
),
],
),
),
),
);
},
),
),
);
},
)
: const SizedBox(),
),
),
],

View File

@@ -1,19 +1,17 @@
import 'package:SEFER/constant/box_name.dart';
import 'package:SEFER/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import '../../constant/colors.dart';
import 'package:SEFER/constant/box_name.dart';
class MyTextForm extends StatelessWidget {
MyTextForm({
super.key,
const MyTextForm({
Key? key,
required this.controller,
required this.label,
required this.hint,
required this.type,
});
}) : super(key: key);
final TextEditingController controller;
final String label, hint;
final TextInputType type;
@@ -24,53 +22,73 @@ class MyTextForm extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 10),
child: SizedBox(
width: Get.width * .8,
child: TextFormField(
keyboardType: type,
cursorColor: AppColor.accentColor,
controller: controller,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: AppColor.primaryColor,
width: 2.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label.tr,
style: TextStyle(
color: CupertinoColors.label,
fontSize: 16,
fontWeight: FontWeight.w600,
),
borderRadius: BorderRadius.circular(10),
),
focusColor: AppColor.accentColor,
fillColor: AppColor.accentColor,
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
labelText: label.tr,
hintText: hint.tr,
),
validator: (value) {
if (value!.isEmpty) {
return '${'Please enter'.tr} $label.'.tr;
}
if (label.contains("Insert card number".tr)) {
if (value.length != 16) {
return "Please enter a valid card 16-digit number.".tr;
}
}
if (type == TextInputType.emailAddress) {
if (!value.contains('@')) {
return 'Please enter a valid email.'.tr;
}
} else if (type == TextInputType.phone) {
if (box.read(BoxName.countryCode) == 'Egypt') {
if (value.length != 11) {
return 'Please enter a valid phone number.'.tr;
}
} else if (value.length != 10) {
return 'Please enter a valid phone number.'.tr;
}
}
return null;
},
const SizedBox(height: 8),
CupertinoTextField(
controller: controller,
keyboardType: type,
placeholder: hint.tr,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: CupertinoColors.systemBackground,
border: Border.all(color: CupertinoColors.systemGrey4),
borderRadius: BorderRadius.circular(8),
),
style: const TextStyle(color: CupertinoColors.label),
placeholderStyle:
const TextStyle(color: CupertinoColors.placeholderText),
),
const SizedBox(height: 4),
ValueListenableBuilder<TextEditingValue>(
valueListenable: controller,
builder: (context, value, child) {
String? errorText = _getErrorText(value.text);
return errorText != null
? Text(
errorText,
style: const TextStyle(
color: CupertinoColors.destructiveRed,
fontSize: 12),
)
: const SizedBox.shrink();
},
),
],
),
),
);
}
String? _getErrorText(String value) {
if (value.isEmpty) {
return '${'Please enter'.tr} $label'.tr;
}
if (type == TextInputType.emailAddress) {
if (!value.contains('@')) {
return 'Please enter a valid email.'.tr;
}
} else if (type == TextInputType.phone) {
final box = GetStorage();
if (box.read(BoxName.countryCode) == 'Egypt') {
if (value.length != 11) {
return 'Please enter a valid phone number.'.tr;
}
} else if (value.length != 10) {
return 'Please enter a valid phone number.'.tr;
}
}
return null;
}
}

View File

@@ -1,43 +1,103 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import '../../constant/colors.dart';
import '../../constant/style.dart';
import '../../controller/functions/tts.dart';
import 'elevated_btn.dart';
import 'package:SEFER/constant/colors.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/controller/functions/tts.dart';
class MyDialog extends GetxController {
void getDialog(String title, String? midTitle, VoidCallback onPressed) {
final textToSpeechController = Get.put(TextToSpeechController());
Get.defaultDialog(
title: title,
titleStyle: AppStyle.title,
middleTextStyle: AppStyle.title,
content: Column(
children: [
IconButton(
Get.dialog(
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: CupertinoAlertDialog(
title: Text(
title,
style: AppStyle.title.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
content: Column(
children: [
CupertinoButton(
onPressed: () async {
await textToSpeechController.speakText(title ?? midTitle!);
},
icon: const Icon(Icons.headphones)),
Text(
midTitle!,
style: AppStyle.title,
)
child: const Icon(CupertinoIcons.headphones,
color: AppColor.primaryColor),
),
Text(
midTitle!,
style: AppStyle.title.copyWith(fontSize: 16),
),
],
),
actions: [
CupertinoDialogAction(
child: Text('Cancel', style: TextStyle(color: AppColor.redColor)),
onPressed: () {
Get.back();
},
),
CupertinoDialogAction(
child:
Text('OK'.tr, style: TextStyle(color: AppColor.greenColor)),
onPressed: onPressed,
),
],
),
confirm: MyElevatedButton(
title: 'Ok'.tr,
onPressed: onPressed,
kolor: AppColor.greenColor,
),
cancel: MyElevatedButton(
title: 'Cancel',
kolor: AppColor.redColor,
onPressed: () {
Get.back();
}));
),
barrierDismissible: false,
);
}
}
class MyDialogContent extends GetxController {
void getDialog(String title, Widget? content, VoidCallback onPressed) {
final textToSpeechController = Get.put(TextToSpeechController());
Get.dialog(
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: CupertinoAlertDialog(
title: Text(
title,
style: AppStyle.title.copyWith(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
content: Column(
children: [
CupertinoButton(
onPressed: () async {
await textToSpeechController.speakText(title);
},
child: const Icon(CupertinoIcons.headphones,
color: AppColor.primaryColor),
),
content!
],
),
actions: [
CupertinoDialogAction(
child: Text('Cancel', style: TextStyle(color: AppColor.redColor)),
onPressed: () {
Get.back();
},
),
CupertinoDialogAction(
child:
Text('OK'.tr, style: TextStyle(color: AppColor.greenColor)),
onPressed: onPressed,
),
],
),
),
barrierDismissible: false,
);
}
}