25-7-26-1
This commit is contained in:
233
lib/views/home/HomePage/about_page.dart
Normal file
233
lib/views/home/HomePage/about_page.dart
Normal file
@@ -0,0 +1,233 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class AboutPage extends StatelessWidget {
|
||||
const AboutPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('About Us'.tr),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Company Logo
|
||||
Center(
|
||||
child: Image.asset(
|
||||
'assets/images/logo.gif', // Replace with your logo image asset path
|
||||
height: 80.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Company Name and Introduction
|
||||
Text(
|
||||
'Tripz LLC',
|
||||
style: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Egypt\'s pioneering ride-sharing service, proudly developed by Arabian and local owners. We prioritize being near you – both our valued passengers and our dedicated captains.'
|
||||
.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
|
||||
// Key Features Section
|
||||
Text(
|
||||
'Why Choose Tripz?'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
|
||||
// Nearest Availability
|
||||
Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.location_solid,
|
||||
color: CupertinoColors.activeBlue),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Closest to You'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'We connect you with the nearest drivers for faster pickups and quicker journeys.'
|
||||
.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle
|
||||
.copyWith(color: CupertinoColors.secondaryLabel),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// High-Level Security
|
||||
Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.shield_fill,
|
||||
color: CupertinoColors.activeGreen),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Uncompromising Security'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.person_2_fill,
|
||||
size: 18, color: CupertinoColors.activeGreen),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'Lady Captains Available'.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle
|
||||
.copyWith(fontSize: 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.recordingtape,
|
||||
size: 18, color: CupertinoColors.activeGreen),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'Recorded Trips (Voice & AI Analysis)'.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle
|
||||
.copyWith(fontSize: 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Fast Support
|
||||
Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.bolt_horizontal_fill,
|
||||
color: CupertinoColors.systemOrange),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Fastest Complaint Response'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'Our dedicated customer service team ensures swift resolution of any issues.'
|
||||
.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle
|
||||
.copyWith(color: CupertinoColors.secondaryLabel),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Affordable Pricing
|
||||
Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.money_dollar_circle_fill,
|
||||
color: CupertinoColors.activeBlue),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Affordable for Everyone'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'Enjoy competitive prices across all trip options, making travel accessible.'
|
||||
.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle
|
||||
.copyWith(color: CupertinoColors.secondaryLabel),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Trip Options
|
||||
Row(
|
||||
children: [
|
||||
const Icon(CupertinoIcons.car_detailed,
|
||||
color: CupertinoColors.systemPurple),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Variety of Trip Choices'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'Choose the trip option that perfectly suits your needs and preferences.'
|
||||
.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle
|
||||
.copyWith(color: CupertinoColors.secondaryLabel),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Passenger Choice
|
||||
Row(
|
||||
children: [
|
||||
Icon(CupertinoIcons.hand_draw_fill,
|
||||
color: CupertinoColors.systemGreen),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Your Choice, Our Priority'.tr,
|
||||
style: CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'Because we are near, you have the flexibility to choose the ride that works best for you.'
|
||||
.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle
|
||||
.copyWith(color: CupertinoColors.secondaryLabel),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
102
lib/views/home/HomePage/contact_us.dart
Normal file
102
lib/views/home/HomePage/contact_us.dart
Normal file
@@ -0,0 +1,102 @@
|
||||
import 'package:Intaleq/constant/colors.dart';
|
||||
import 'package:Intaleq/constant/style.dart';
|
||||
// ignore: unused_import
|
||||
import 'package:Intaleq/controller/functions/launch.dart';
|
||||
import 'package:Intaleq/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/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: ListView(
|
||||
// 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(
|
||||
'Intaleq 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(
|
||||
'Intaleq 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
228
lib/views/home/HomePage/frequentlyQuestionsPage.dart
Normal file
228
lib/views/home/HomePage/frequentlyQuestionsPage.dart
Normal file
@@ -0,0 +1,228 @@
|
||||
import 'package:Intaleq/views/home/HomePage/contact_us.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class FrequentlyQuestionsPage extends StatelessWidget {
|
||||
const FrequentlyQuestionsPage({super.key});
|
||||
|
||||
void _showAnswerDialog(BuildContext context, String question, String answer) {
|
||||
showCupertinoDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => CupertinoAlertDialog(
|
||||
title: Text(question,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold, color: Colors.indigo)),
|
||||
content: Text(answer),
|
||||
actions: <CupertinoDialogAction>[
|
||||
CupertinoDialogAction(
|
||||
isDefaultAction: true,
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: const Text('Close'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
backgroundColor: Colors.indigo,
|
||||
middle: Text(
|
||||
'Frequently Asked Questions'.tr,
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
CupertinoListSection.insetGrouped(
|
||||
header: Text(
|
||||
'Getting Started'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: <CupertinoListTile>[
|
||||
CupertinoListTile(
|
||||
leading: const Icon(
|
||||
CupertinoIcons.car_detailed,
|
||||
color: Colors.indigo,
|
||||
),
|
||||
title: Text('How do I request a ride?'.tr),
|
||||
trailing: const CupertinoListTileChevron(),
|
||||
onTap: () => _showAnswerDialog(
|
||||
context,
|
||||
'How do I request a ride?'.tr,
|
||||
'Simply open the Intaleq app, enter your destination, and tap "Request Ride". The app will connect you with a nearby driver.'
|
||||
.tr,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CupertinoListSection.insetGrouped(
|
||||
header: Text(
|
||||
'Vehicle Options'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: <CupertinoListTile>[
|
||||
CupertinoListTile(
|
||||
leading: const Icon(
|
||||
CupertinoIcons.car_fill,
|
||||
color: Colors.blue,
|
||||
),
|
||||
title: Text('What types of vehicles are available?'.tr),
|
||||
trailing: const CupertinoListTileChevron(),
|
||||
onTap: () => _showAnswerDialog(
|
||||
context,
|
||||
'What types of vehicles are available?'.tr,
|
||||
'Intaleq offers a variety of options including Economy, Comfort, and Luxury to suit your needs and budget.'
|
||||
.tr,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CupertinoListSection.insetGrouped(
|
||||
header: Text(
|
||||
'Payments'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: <CupertinoListTile>[
|
||||
CupertinoListTile(
|
||||
leading: const Icon(
|
||||
CupertinoIcons.creditcard,
|
||||
color: Colors.green,
|
||||
),
|
||||
title: Text('How can I pay for my ride?'.tr),
|
||||
trailing: const CupertinoListTileChevron(),
|
||||
onTap: () => _showAnswerDialog(
|
||||
context,
|
||||
'How can I pay for my ride?'.tr,
|
||||
'You can pay for your ride using cash or credit/debit card. You can select your preferred payment method before confirming your ride.'
|
||||
.tr,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CupertinoListSection.insetGrouped(
|
||||
header: Text(
|
||||
'Ride Management'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: <CupertinoListTile>[
|
||||
CupertinoListTile(
|
||||
leading: const Icon(
|
||||
CupertinoIcons.xmark_circle_fill,
|
||||
color: Colors.red,
|
||||
),
|
||||
title: Text('Can I cancel my ride?'.tr),
|
||||
trailing: const CupertinoListTileChevron(),
|
||||
onTap: () => _showAnswerDialog(
|
||||
context,
|
||||
'Can I cancel my ride?'.tr,
|
||||
'Yes, you can cancel your ride, but please note that cancellation fees may apply depending on how far in advance you cancel.'
|
||||
.tr,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CupertinoListSection.insetGrouped(
|
||||
header: Text(
|
||||
'For Drivers'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: <CupertinoListTile>[
|
||||
CupertinoListTile(
|
||||
leading: const Icon(
|
||||
CupertinoIcons.person_crop_circle_fill,
|
||||
color: Colors.orange,
|
||||
),
|
||||
title: Text('Driver Registration & Requirements'.tr),
|
||||
trailing: const CupertinoListTileChevron(),
|
||||
onTap: () => showCupertinoDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => CupertinoAlertDialog(
|
||||
title: Text('Driver Registration'.tr,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.indigo)),
|
||||
content: Text(
|
||||
'To register as a driver or learn about the requirements, please visit our website or contact Intaleq support directly.'
|
||||
.tr),
|
||||
actions: <CupertinoDialogAction>[
|
||||
CupertinoDialogAction(
|
||||
isDefaultAction: true,
|
||||
onPressed: () {
|
||||
Get.to(() => ContactUsPage());
|
||||
// Optionally, you can open a URL here
|
||||
},
|
||||
child: Text('Visit Website/Contact Support'.tr),
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Close'.tr),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CupertinoListSection.insetGrouped(
|
||||
header: Text(
|
||||
'Communication'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: <CupertinoListTile>[
|
||||
CupertinoListTile(
|
||||
leading: const Icon(
|
||||
CupertinoIcons.chat_bubble_2_fill,
|
||||
color: Colors.purple,
|
||||
),
|
||||
title: Text(
|
||||
'How do I communicate with the other party (passenger/driver)?'
|
||||
.tr),
|
||||
trailing: const CupertinoListTileChevron(),
|
||||
onTap: () => _showAnswerDialog(
|
||||
context,
|
||||
'How do I communicate with the other party (passenger/driver)?'
|
||||
.tr,
|
||||
'You can communicate with your driver or passenger through the in-app chat feature once a ride is confirmed.'
|
||||
.tr,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CupertinoListSection.insetGrouped(
|
||||
header: Text(
|
||||
'Safety & Security'.tr,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: <CupertinoListTile>[
|
||||
CupertinoListTile(
|
||||
leading: const Icon(
|
||||
CupertinoIcons.shield_fill,
|
||||
color: Colors.teal,
|
||||
),
|
||||
title: Text('What safety measures does Intaleq offer?'.tr),
|
||||
trailing: const CupertinoListTileChevron(),
|
||||
onTap: () => _showAnswerDialog(
|
||||
context,
|
||||
'What safety measures does Intaleq offer?'.tr,
|
||||
'Intaleq offers various safety features including driver verification, in-app trip tracking, emergency contact options, and the ability to share your trip status with trusted contacts.'
|
||||
.tr,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20), // Add some bottom padding
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
569
lib/views/home/HomePage/share_app_page.dart
Normal file
569
lib/views/home/HomePage/share_app_page.dart
Normal file
@@ -0,0 +1,569 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../constant/colors.dart';
|
||||
import '../../../controller/home/profile/invit_controller.dart';
|
||||
import '../../../print.dart';
|
||||
|
||||
class ShareAppPage extends StatelessWidget {
|
||||
final InviteController controller = Get.put(InviteController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: CupertinoColors.systemBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: CupertinoColors.systemBackground,
|
||||
elevation: 0,
|
||||
title: Text(
|
||||
'Invite'.tr,
|
||||
style: const TextStyle(color: CupertinoColors.label),
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios, color: AppColor.blueColor),
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: GetBuilder<InviteController>(
|
||||
builder: (controller) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: _buildPassengerTab(context),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPassengerTab(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.systemGrey6,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Share this code with your friends and earn rewards when they use it!"
|
||||
.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
color: CupertinoColors.secondaryLabel,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildPhoneInput(),
|
||||
const SizedBox(height: 20),
|
||||
_buildActionButtonsPassengers(),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
_buildInvitationsListPassengers(context),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// Widget _buildPhoneInput() {
|
||||
// return Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: CupertinoColors.systemGrey6,
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// ),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: CupertinoTextField.borderless(
|
||||
// controller: controller.invitePhoneController,
|
||||
// placeholder: 'Enter phone'.tr,
|
||||
// padding: const EdgeInsets.all(12),
|
||||
// keyboardType: TextInputType.phone,
|
||||
// ),
|
||||
// ),
|
||||
// CupertinoButton(
|
||||
// child: const Icon(CupertinoIcons.person_badge_plus,
|
||||
// color: AppColor.blueColor),
|
||||
// onPressed: () async {
|
||||
// await controller.pickContacts();
|
||||
// if (controller.contacts.isNotEmpty) {
|
||||
// if (box.read(BoxName.isSavedPhones) == null) {
|
||||
// controller.savePhoneToServer();
|
||||
// box.write(BoxName.isSavedPhones, true);
|
||||
// }
|
||||
// _showContactsDialog(Get.context!);
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
Widget _buildPhoneInput() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.systemGrey6,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoTextField.borderless(
|
||||
controller: controller.invitePhoneController,
|
||||
placeholder: 'Enter phone'.tr,
|
||||
padding: const EdgeInsets.all(12),
|
||||
keyboardType: TextInputType.phone,
|
||||
),
|
||||
),
|
||||
CupertinoButton(
|
||||
child: const Icon(CupertinoIcons.person_badge_plus,
|
||||
color: AppColor.blueColor),
|
||||
onPressed: () async {
|
||||
await controller.pickContacts();
|
||||
Log.print('contacts: ${controller.contacts}');
|
||||
if (controller.contacts.isNotEmpty) {
|
||||
_showContactsDialog(Get
|
||||
.context!); // Show contacts dialog after loading contacts
|
||||
} else {
|
||||
Get.snackbar(
|
||||
'No contacts available'.tr,
|
||||
'Please add contacts to your phone.'.tr,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildActionButtonsPassengers() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: CupertinoButton(
|
||||
color: AppColor.blueColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
onPressed: controller.sendInviteToPassenger,
|
||||
child: Text(
|
||||
'Send Invite'.tr,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: CupertinoColors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: CupertinoButton(
|
||||
color: AppColor.blueColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
child: Text(
|
||||
'Show Invitations'.tr,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: CupertinoColors.white,
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
controller.fetchDriverStatsPassengers();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInvitationsListPassengers(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: Get.height * .4,
|
||||
child: controller.driverInvitationDataToPassengers.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
"No invitation found yet!".tr,
|
||||
style: const TextStyle(
|
||||
color: CupertinoColors.secondaryLabel,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: controller.driverInvitationDataToPassengers.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildInvitationItemPassengers(context, index);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInvitationItemPassengers(BuildContext context, int index) {
|
||||
// Extracting the data from the sample JSON-like structure
|
||||
var invitation = controller.driverInvitationDataToPassengers[index];
|
||||
|
||||
int countOfInvitDriver =
|
||||
int.tryParse(invitation['countOfInvitDriver']?.toString() ?? '0') ?? 0;
|
||||
double progressValue = (countOfInvitDriver / 10.0).clamp(0.0, 1.0);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
controller.onSelectPassengerInvitation(index);
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.systemGrey6,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
invitation['passengerName']
|
||||
.toString(), // Handle null or missing data
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: CupertinoColors.label,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: LinearProgressIndicator(
|
||||
value: progressValue,
|
||||
backgroundColor: CupertinoColors.systemGrey4,
|
||||
valueColor:
|
||||
const AlwaysStoppedAnimation<Color>(AppColor.blueColor),
|
||||
minHeight: 6,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'$countOfInvitDriver / 2 ${'Trip'.tr}', // Show trips completed
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: CupertinoColors.secondaryLabel,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPassengerStats(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.systemGrey6,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Your Rewards".tr,
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: CupertinoColors.label,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildStatItem(
|
||||
context,
|
||||
"Total Invites".tr,
|
||||
controller.driverInvitationDataToPassengers[0]['countOfInvitDriver']
|
||||
.toString(),
|
||||
),
|
||||
_buildStatItem(
|
||||
context,
|
||||
"Active Users".tr,
|
||||
controller.driverInvitationDataToPassengers[0]['passengerName']
|
||||
.toString(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatItem(BuildContext context, String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
color: CupertinoColors.label,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColor.blueColor,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showContactsDialog(BuildContext context) {
|
||||
Get.defaultDialog(
|
||||
title: 'Choose from contact'.tr,
|
||||
content: SizedBox(
|
||||
height: 400,
|
||||
width: 400,
|
||||
child: Column(
|
||||
children: [
|
||||
// Header with cancel and title
|
||||
// Container(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
// decoration: const BoxDecoration(
|
||||
// borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||
// color: CupertinoColors.systemGrey6,
|
||||
// ),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// CupertinoButton(
|
||||
// padding: EdgeInsets.zero,
|
||||
// child: Text(
|
||||
// 'Cancel'.tr,
|
||||
// style: const TextStyle(color: CupertinoColors.systemBlue),
|
||||
// ),
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
// ),
|
||||
// Container(
|
||||
// child: Text('Choose from contact'.tr,
|
||||
// style: AppStyle.title)),
|
||||
// const SizedBox(width: 60), // Balance for Cancel button
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// Contact list
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: controller.contactMaps.length,
|
||||
itemBuilder: (context, index) {
|
||||
final contact = controller.contactMaps[index];
|
||||
return CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () {
|
||||
controller.selectPhone(contact['phones'].toString());
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.systemBackground,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: CupertinoColors.separator.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// Display contact name and phone number
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
contact['name'],
|
||||
style: const TextStyle(
|
||||
color: CupertinoColors.label,
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
controller.formatPhoneNumber(
|
||||
contact['phones'][0].toString()),
|
||||
style: const TextStyle(
|
||||
color: CupertinoColors.secondaryLabel,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Chevron icon for selection
|
||||
const Icon(
|
||||
CupertinoIcons.chevron_forward,
|
||||
color: CupertinoColors.systemGrey2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
// showCupertinoModalPopup(
|
||||
// context: context,
|
||||
// builder: (BuildContext context) => Container(
|
||||
// height: 400,
|
||||
// decoration: BoxDecoration(
|
||||
// color: CupertinoColors.systemBackground,
|
||||
// borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: CupertinoColors.black.withOpacity(0.2),
|
||||
// offset: const Offset(0, -4),
|
||||
// blurRadius: 10,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: Column(
|
||||
// children: [
|
||||
// // Header with cancel and title
|
||||
// Container(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
// decoration: const BoxDecoration(
|
||||
// borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||
// color: CupertinoColors.systemGrey6,
|
||||
// ),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// CupertinoButton(
|
||||
// padding: EdgeInsets.zero,
|
||||
// child: Text(
|
||||
// 'Cancel'.tr,
|
||||
// style: const TextStyle(color: CupertinoColors.systemBlue),
|
||||
// ),
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
// ),
|
||||
// Container(
|
||||
// child: Text('Choose from contact'.tr,
|
||||
// style: AppStyle.title)),
|
||||
// const SizedBox(width: 60), // Balance for Cancel button
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// // Contact list
|
||||
// Expanded(
|
||||
// child: ListView.builder(
|
||||
// itemCount: controller.contactMaps.length,
|
||||
// itemBuilder: (context, index) {
|
||||
// final contact = controller.contactMaps[index];
|
||||
// return CupertinoButton(
|
||||
// padding: EdgeInsets.zero,
|
||||
// onPressed: () {
|
||||
// controller.selectPhone(contact['phones'].toString());
|
||||
// },
|
||||
// child: Container(
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// horizontal: 16, vertical: 12),
|
||||
// decoration: BoxDecoration(
|
||||
// color: CupertinoColors.systemBackground,
|
||||
// border: Border(
|
||||
// bottom: BorderSide(
|
||||
// color: CupertinoColors.separator.withOpacity(0.5),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// // Display contact name and phone number
|
||||
// Expanded(
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// contact['name'],
|
||||
// style: const TextStyle(
|
||||
// color: CupertinoColors.label,
|
||||
// fontSize: 17,
|
||||
// fontWeight: FontWeight.w500,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// controller.formatPhoneNumber(
|
||||
// contact['phones'][0].toString()),
|
||||
// style: const TextStyle(
|
||||
// color: CupertinoColors.secondaryLabel,
|
||||
// fontSize: 15,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// // Chevron icon for selection
|
||||
// const Icon(
|
||||
// CupertinoIcons.chevron_forward,
|
||||
// color: CupertinoColors.systemGrey2,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
}
|
||||
}
|
||||
105
lib/views/home/HomePage/trip_monitor/trip_link_monitor.dart
Normal file
105
lib/views/home/HomePage/trip_monitor/trip_link_monitor.dart
Normal file
@@ -0,0 +1,105 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:Intaleq/controller/home/trip_monitor_controller.dart';
|
||||
import 'package:Intaleq/views/widgets/my_scafold.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:vibration/vibration.dart';
|
||||
|
||||
import '../../../../constant/colors.dart';
|
||||
import '../../../../constant/style.dart';
|
||||
import '../../../widgets/elevated_btn.dart';
|
||||
|
||||
class TripMonitor extends StatelessWidget {
|
||||
const TripMonitor({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final params = Get.parameters;
|
||||
// Use params to initialize your controller or pass data
|
||||
Get.put(TripMonitorController()).init();
|
||||
return GetBuilder<TripMonitorController>(builder: (tripMonitorController) {
|
||||
return MyScafolld(
|
||||
title: 'Trip Monitor'.tr,
|
||||
body: [
|
||||
GoogleMap(
|
||||
onMapCreated: tripMonitorController.onMapCreated,
|
||||
initialCameraPosition: CameraPosition(
|
||||
// bearing: 45,
|
||||
target: tripMonitorController.parentLocation,
|
||||
zoom: 16,
|
||||
tilt: 40,
|
||||
),
|
||||
// onCameraMove: (position) {},
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: MarkerId('start'.tr),
|
||||
position: tripMonitorController.parentLocation,
|
||||
draggable: true,
|
||||
icon: tripMonitorController.tripData['message'][0]['model']
|
||||
.contains('دراجة')
|
||||
? tripMonitorController.motoIcon
|
||||
: tripMonitorController.tripData['message'][0]['model']
|
||||
['gender'] ==
|
||||
'Male'
|
||||
? tripMonitorController.carIcon
|
||||
: tripMonitorController.ladyIcon,
|
||||
rotation: tripMonitorController.rotation,
|
||||
),
|
||||
},
|
||||
),
|
||||
speedCircle()
|
||||
],
|
||||
isleading: true,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
GetBuilder<TripMonitorController> speedCircle() {
|
||||
if (Get.find<TripMonitorController>().speed > 100) {
|
||||
if (Platform.isIOS) {
|
||||
HapticFeedback.selectionClick();
|
||||
} else {
|
||||
Vibration.vibrate(duration: 1000);
|
||||
}
|
||||
Get.defaultDialog(
|
||||
barrierDismissible: false,
|
||||
titleStyle: AppStyle.title,
|
||||
title: 'Speed Over'.tr,
|
||||
middleText: 'Please slow down'.tr,
|
||||
middleTextStyle: AppStyle.title,
|
||||
confirm: MyElevatedButton(
|
||||
title: 'I will slow down'.tr,
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
);
|
||||
}
|
||||
return GetBuilder<TripMonitorController>(
|
||||
builder: (tripMonitorController) {
|
||||
return Positioned(
|
||||
bottom: 25,
|
||||
right: 100,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: tripMonitorController.speed > 100
|
||||
? Colors.red
|
||||
: AppColor.secondaryColor,
|
||||
border: Border.all(width: 3, color: AppColor.redColor),
|
||||
),
|
||||
height: 60,
|
||||
width: 60,
|
||||
child: Center(
|
||||
child: Text(
|
||||
tripMonitorController.speed.toStringAsFixed(0),
|
||||
style: AppStyle.number,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
111
lib/views/home/HomePage/trip_monitor/trip_monitor.dart
Normal file
111
lib/views/home/HomePage/trip_monitor/trip_monitor.dart
Normal file
@@ -0,0 +1,111 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:Intaleq/controller/home/trip_monitor_controller.dart';
|
||||
import 'package:Intaleq/views/widgets/my_scafold.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:vibration/vibration.dart';
|
||||
|
||||
import '../../../../constant/colors.dart';
|
||||
import '../../../../constant/style.dart';
|
||||
import '../../../widgets/elevated_btn.dart';
|
||||
|
||||
class TripMonitor extends StatelessWidget {
|
||||
const TripMonitor({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final params = Get.parameters;
|
||||
final arguments = Get.arguments as Map<String, dynamic>?;
|
||||
|
||||
// Use params or arguments to initialize your controller
|
||||
final controller = Get.put(TripMonitorController());
|
||||
controller.init(
|
||||
rideId: params['rideId'] ?? arguments?['rideId'],
|
||||
driverId: params['driverId'] ?? arguments?['driverId'],
|
||||
);
|
||||
return GetBuilder<TripMonitorController>(builder: (tripMonitorController) {
|
||||
return MyScafolld(
|
||||
title: 'Trip Monitor'.tr,
|
||||
body: [
|
||||
GoogleMap(
|
||||
onMapCreated: tripMonitorController.onMapCreated,
|
||||
initialCameraPosition: CameraPosition(
|
||||
// bearing: 45,
|
||||
target: tripMonitorController.parentLocation,
|
||||
zoom: 16,
|
||||
tilt: 40,
|
||||
),
|
||||
// onCameraMove: (position) {},
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: MarkerId('start'.tr),
|
||||
position: tripMonitorController.parentLocation,
|
||||
draggable: true,
|
||||
icon: tripMonitorController.tripData['message'][0]['model']
|
||||
.contains('دراجة')
|
||||
? tripMonitorController.motoIcon
|
||||
: tripMonitorController.tripData['message'][0]['model']
|
||||
['gender'] ==
|
||||
'Male'
|
||||
? tripMonitorController.carIcon
|
||||
: tripMonitorController.ladyIcon,
|
||||
rotation: tripMonitorController.rotation,
|
||||
),
|
||||
},
|
||||
),
|
||||
speedCircle()
|
||||
],
|
||||
isleading: true,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
GetBuilder<TripMonitorController> speedCircle() {
|
||||
if (Get.find<TripMonitorController>().speed > 100) {
|
||||
if (Platform.isIOS) {
|
||||
HapticFeedback.selectionClick();
|
||||
} else {
|
||||
Vibration.vibrate(duration: 1000);
|
||||
}
|
||||
Get.defaultDialog(
|
||||
barrierDismissible: false,
|
||||
titleStyle: AppStyle.title,
|
||||
title: 'Speed Over'.tr,
|
||||
middleText: 'Please slow down'.tr,
|
||||
middleTextStyle: AppStyle.title,
|
||||
confirm: MyElevatedButton(
|
||||
title: 'I will slow down'.tr,
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
);
|
||||
}
|
||||
return GetBuilder<TripMonitorController>(
|
||||
builder: (tripMonitorController) {
|
||||
return Positioned(
|
||||
bottom: 25,
|
||||
right: 100,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: tripMonitorController.speed > 100
|
||||
? Colors.red
|
||||
: AppColor.secondaryColor,
|
||||
border: Border.all(width: 3, color: AppColor.redColor),
|
||||
),
|
||||
height: 60,
|
||||
width: 60,
|
||||
child: Center(
|
||||
child: Text(
|
||||
tripMonitorController.speed.toStringAsFixed(0),
|
||||
style: AppStyle.number,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
211
lib/views/home/HomePage/trip_record_page.dart
Normal file
211
lib/views/home/HomePage/trip_record_page.dart
Normal file
@@ -0,0 +1,211 @@
|
||||
import 'package:Intaleq/views/widgets/my_scafold.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:share/share.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../../../controller/functions/audio_record1.dart';
|
||||
|
||||
class TripsRecordedPage extends StatelessWidget {
|
||||
const TripsRecordedPage({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MyScafolld(
|
||||
title: 'Trips recorded'.tr,
|
||||
body: [
|
||||
GetBuilder<AudioRecorderController>(builder: (audio) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
FutureBuilder<List<String>>(
|
||||
future: audio.getRecordedFiles(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(
|
||||
child: CupertinoActivityIndicator());
|
||||
} else if (snapshot.hasData) {
|
||||
final recordedFiles = snapshot.data!;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: () async {
|
||||
String? selectedFile =
|
||||
await showCupertinoModalPopup<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
title: Text('Select a File'.tr),
|
||||
actions: recordedFiles
|
||||
.map(
|
||||
(file) => CupertinoActionSheetAction(
|
||||
child: Text(path.basename(file)),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(file);
|
||||
},
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
if (selectedFile != null) {
|
||||
audio.selectedFilePath = selectedFile;
|
||||
audio.playRecordedFile(selectedFile);
|
||||
audio.update();
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
audio.selectedFilePath != null
|
||||
? path.basename(audio.selectedFilePath!)
|
||||
: 'Select a File'.tr,
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.actionTextStyle
|
||||
.copyWith(color: CupertinoColors.activeBlue),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text('Error: ${snapshot.error}'),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
// Cupertino-style slider for seeking audio
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: CupertinoSlider(
|
||||
value: audio.totalDuration > 0
|
||||
? audio.currentPosition / audio.totalDuration
|
||||
: 0.0, // Normalize to a value between 0.0 and 1.0
|
||||
min: 0.0,
|
||||
max: 1.0, // Maximum value is now 1.0
|
||||
activeColor: CupertinoColors.activeBlue,
|
||||
onChanged: (value) {
|
||||
final newPosition = value * audio.totalDuration;
|
||||
audio.currentPosition = newPosition;
|
||||
audio.audioPlayer
|
||||
.seek(Duration(seconds: newPosition.toInt()));
|
||||
audio.update();
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
// iOS-style playback controls
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 16.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
child: Icon(
|
||||
audio.isPlaying
|
||||
? CupertinoIcons.pause
|
||||
: CupertinoIcons.play_arrow,
|
||||
color: CupertinoColors.activeBlue,
|
||||
),
|
||||
onPressed: () {
|
||||
if (audio.isPlaying) {
|
||||
audio.pausePlayback();
|
||||
} else {
|
||||
audio.resumePlayback();
|
||||
}
|
||||
audio.update();
|
||||
},
|
||||
),
|
||||
CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
child: const Icon(CupertinoIcons.stop,
|
||||
color: CupertinoColors.destructiveRed),
|
||||
onPressed: () {
|
||||
audio.stopPlayback();
|
||||
audio.update();
|
||||
},
|
||||
),
|
||||
CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
child: const Icon(CupertinoIcons.delete,
|
||||
color: CupertinoColors.destructiveRed),
|
||||
onPressed: () async {
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
title: Text('Are you sure?'.tr),
|
||||
message: Text(
|
||||
'This will delete all recorded files from your device.'
|
||||
.tr,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
actions: [
|
||||
CupertinoActionSheetAction(
|
||||
isDestructiveAction: true,
|
||||
onPressed: () async {
|
||||
await audio.deleteAllRecordedFiles();
|
||||
Navigator.pop(context);
|
||||
audio.update();
|
||||
},
|
||||
child: Text('Delete'.tr),
|
||||
),
|
||||
],
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text('Cancel'.tr),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// File selection and sharing
|
||||
if (audio.selectedFilePath != null)
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
color: CupertinoColors.systemGrey6,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Selected file: ${path.basename(audio.selectedFilePath!)}',
|
||||
style: CupertinoTheme.of(context)
|
||||
.textTheme
|
||||
.textStyle,
|
||||
),
|
||||
CupertinoButton(
|
||||
padding: EdgeInsets.zero,
|
||||
child: const Icon(CupertinoIcons.share),
|
||||
onPressed: () {
|
||||
Share.shareFiles([audio.selectedFilePath!]);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
],
|
||||
isleading: true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user