This commit is contained in:
Hamza-Ayed
2023-10-19 20:19:02 +03:00
parent 805754a599
commit 02bdc83e72
14 changed files with 407 additions and 121 deletions

View File

@@ -67,6 +67,10 @@ class AppLink {
static const String addCarsLocationByPassenger = "$location/add.php";
static const String deleteCarsLocationByPassenger = "$location/delete.php";
static const String updateCarsLocationByPassenger = "$location/update.php";
static const String getTotalDriverDuration =
"$location/getTotalDriverDuration.php";
static const String getTotalDriverDurationToday =
"$location/getTotalDriverDurationToday.php";
//==================Blog=============
static const String profile = 'https://ride.mobile-app.store/ride/profile';

View File

@@ -36,14 +36,14 @@ class AppStyle {
BoxShadow(
color: AppColor.accentColor,
offset: Offset(-3, -3),
blurRadius: 1,
spreadRadius: 1,
blurRadius: 0,
spreadRadius: 0,
blurStyle: BlurStyle.outer),
BoxShadow(
color: AppColor.accentColor,
offset: Offset(3, 3),
blurRadius: 1,
spreadRadius: 1,
blurRadius: 0,
spreadRadius: 0,
blurStyle: BlurStyle.outer)
]);
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
class LineChartPainter extends CustomPainter {
final List<double> data;
LineChartPainter(this.data);
@override
void paint(Canvas canvas, Size size) {
// Calculate the scale factor.
final scaleFactor = size.height / 240;
// Draw the line chart.
for (var i = 0; i < data.length - 1; i++) {
final x1 = i * size.width / data.length;
final y1 = data[i] * scaleFactor;
final x2 = (i + 1) * size.width / data.length;
final y2 = data[i + 1] * scaleFactor;
canvas.drawLine(Offset(x1, y1), Offset(x2, y2), Paint());
}
}
@override
bool shouldRepaint(LineChartPainter oldDelegate) => false;
}

View File

@@ -0,0 +1,77 @@
import 'dart:convert';
import 'package:flutter/animation.dart';
import 'package:get/get.dart';
import 'package:ride/constant/box_name.dart';
import 'package:ride/constant/links.dart';
import 'package:ride/controller/functions/crud.dart';
import 'package:ride/main.dart';
class DurationController extends GetxController
with GetSingleTickerProviderStateMixin {
final data = <DurationData>[].obs;
late AnimationController animationController;
@override
void onInit() {
super.onInit();
fetchData();
animationController = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 500), // Adjust the animation duration as needed
);
animationController.forward(); // Start the animation
}
@override
void onClose() {
animationController.dispose();
super.onClose();
}
Map<String, dynamic> jsonData = {};
bool isLoading = false;
String totalDurationToday = '';
Future<void> fetchData() async {
isLoading = true;
update(); // Notify the observers about the loading state change
var res = await CRUD().get(
link: AppLink.getTotalDriverDuration,
payload: {'driver_id': box.read(BoxName.driverID)},
);
jsonData = jsonDecode(res);
final parsedData = parseData(jsonData['message']);
data.value = parsedData;
isLoading = false;
update(); // Notify the observers about the data and loading state change
}
List<DurationData> parseData(List<dynamic> json) {
return json.map((entry) {
final Map<String, dynamic> entryMap = entry;
final day = DateTime.parse(entryMap['day']);
final totalDuration = _parseDuration(entryMap['total_duration']);
return DurationData(day, totalDuration);
}).toList();
}
Duration _parseDuration(String durationString) {
final parts = durationString.split(':');
final hours = int.parse(parts[0]);
final minutes = int.parse(parts[1]);
final seconds = int.parse(parts[2]);
return Duration(hours: hours, minutes: minutes, seconds: seconds);
}
}
class DurationData {
final DateTime day;
final Duration totalDuration;
DurationData(this.day, this.totalDuration);
}

View File

@@ -15,7 +15,9 @@ class HomeCaptainController extends GetxController {
Duration activeDuration = Duration.zero;
Timer? activeTimer;
Map data = {};
String totalToday = '0';
String totalMoneyToday = '0';
String totalDurationToday = '0';
Timer? timer;
// Inject the LocationController class
final locationController = Get.find<LocationController>();
@@ -55,10 +57,22 @@ class HomeCaptainController extends GetxController {
return totalDuration;
}
void startPeriodicExecution() {
Timer.periodic(const Duration(seconds: 30), (timer) async {
await getCaptainDurationOnToday();
});
}
void stopTimer() {
print('Stopping timer');
timer?.cancel();
}
@override
void onInit() async {
addToken();
getPaymentToday();
startPeriodicExecution();
super.onInit();
}
@@ -75,13 +89,24 @@ class HomeCaptainController extends GetxController {
link: AppLink.getDriverpaymentToday,
payload: {'driverID': box.read(BoxName.driverID).toString()});
data = jsonDecode(res);
totalToday = data['message'][0]['total_amount'];
totalMoneyToday = data['message'][0]['total_amount'];
update();
}
Future<void> getCaptainDurationOnToday() async {
var res = await CRUD().get(
link: AppLink.getTotalDriverDurationToday,
payload: {'driver_id': box.read(BoxName.driverID).toString()});
data = jsonDecode(res);
totalDurationToday = data['message'][0]['total_duration'];
update();
}
@override
void dispose() {
activeTimer?.cancel();
stopTimer();
super.dispose();
}
}

View File

@@ -393,51 +393,47 @@ class MapPassengerController extends GetxController {
}
Future getCarsLocationByPassenger() async {
if (rideConfirm == false) {
carsLocationByPassenger = [];
LatLngBounds bounds =
calculateBounds(myLocation.latitude, myLocation.longitude, 8000);
print(
'Southwest: ${bounds.southwest.latitude}, ${bounds.southwest.longitude}');
print(
'Northeast: ${bounds.northeast.latitude}, ${bounds.northeast.longitude}');
// if (rideConfirm == false) {
carsLocationByPassenger = [];
LatLngBounds bounds =
calculateBounds(myLocation.latitude, myLocation.longitude, 8000);
print(
'Southwest: ${bounds.southwest.latitude}, ${bounds.southwest.longitude}');
print(
'Northeast: ${bounds.northeast.latitude}, ${bounds.northeast.longitude}');
var res =
await CRUD().get(link: AppLink.getCarsLocationByPassenger, payload: {
'southwestLat': southwest.latitude.toString(),
'southwestLon': southwest.longitude.toString(),
'northeastLat': northeast.latitude.toString(),
'northeastLon': northeast.longitude.toString(),
});
if (res == 'failure') {
Get.defaultDialog(
title: 'No Car in your site.Sorry!',
middleText: '',
confirm: MyElevatedButton(
title: 'Back',
onPressed: () {
Get.back();
markerReloadingTimer.cancel();
}));
} else {
dataCarsLocationByPassenger = jsonDecode(res);
// print(dataCarsLocationByPassenger);
driverId = dataCarsLocationByPassenger['message'][carsOrder]
['driver_id']
.toString();
// print('driverId==============$driverId');
for (var i = 0;
i < dataCarsLocationByPassenger['message'].length;
i++) {
carsLocationByPassenger.add(LatLng(
double.parse(
dataCarsLocationByPassenger['message'][i]['latitude']),
double.parse(
dataCarsLocationByPassenger['message'][i]['longitude'])));
}
update();
var res =
await CRUD().get(link: AppLink.getCarsLocationByPassenger, payload: {
'southwestLat': southwest.latitude.toString(),
'southwestLon': southwest.longitude.toString(),
'northeastLat': northeast.latitude.toString(),
'northeastLon': northeast.longitude.toString(),
});
if (res == 'failure') {
Get.defaultDialog(
title: 'No Car in your site.Sorry!',
middleText: '',
confirm: MyElevatedButton(
title: 'Back',
onPressed: () {
Get.back();
markerReloadingTimer.cancel();
}));
} else {
dataCarsLocationByPassenger = jsonDecode(res);
// print(dataCarsLocationByPassenger);
driverId = dataCarsLocationByPassenger['message'][carsOrder]['driver_id']
.toString();
// print('driverId==============$driverId');
for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) {
carsLocationByPassenger.add(LatLng(
double.parse(dataCarsLocationByPassenger['message'][i]['latitude']),
double.parse(
dataCarsLocationByPassenger['message'][i]['longitude'])));
}
update();
// }
}
}
@@ -771,67 +767,72 @@ class MapPassengerController extends GetxController {
void getNearestDriverByPassengerLocation() async {
if (polyLines.isEmpty || data.isEmpty) {
double nearestDistance = double.infinity;
for (var i = 0; i < dataCarsLocationByPassenger['message'].length; i++) {
var carLocation = dataCarsLocationByPassenger['message'][i];
if (rideConfirm == false) {
double nearestDistance = double.infinity;
for (var i = 0;
i < dataCarsLocationByPassenger['message'].length;
i++) {
var carLocation = dataCarsLocationByPassenger['message'][i];
// double distance1 = Geolocator.distanceBetween(
// mylocation.latitude,
// mylocation.longitude,
// double.parse(carLocation['latitude']),
// double.parse(carLocation['longitude']),
// );
// if (distance1 < nearestDistance) {
// nearestDistance = distance1;
// // nearestCarLocation = carLocation;
// nearestCar = CarLocation(
// distance: distance1,
// id: carLocation['driver_id'],
// latitude: double.parse(carLocation['latitude']),
// longitude: double.parse(carLocation['longitude']),
// );
// }
// isloading = true;
update();
// Make API request to get exact distance and duration
String apiUrl =
'${AppLink.googleMapsLink}distancematrix/json?destinations=${carLocation['latitude']},${carLocation['longitude']}&origins=${myLocation.latitude},${myLocation.longitude}&units=metric&key=${AppCredintials.mapAPIKEY}';
var response = await CRUD().getGoogleApi(link: apiUrl, payload: {});
if (response['status'] == "OK") {
var data = response;
// Extract distance and duration from the response and handle accordingly
int distance1 = data['rows'][0]['elements'][0]['distance']['value'];
distanceByPassenger =
data['rows'][0]['elements'][0]['distance']['text'];
duration1 = data['rows'][0]['elements'][0]['duration']['value'];
durationFromDriverToPassenger = Duration(seconds: duration1.toInt());
newTime1 = currentTime.add(durationFromDriverToPassenger);
timeFromDriverToPassenger =
newTime1.add(Duration(minutes: 2.toInt()));
durationByPassenger =
data['rows'][0]['elements'][0]['duration']['text'];
// double distance1 = Geolocator.distanceBetween(
// mylocation.latitude,
// mylocation.longitude,
// double.parse(carLocation['latitude']),
// double.parse(carLocation['longitude']),
// );
// if (distance1 < nearestDistance) {
// nearestDistance = distance1;
// // nearestCarLocation = carLocation;
// nearestCar = CarLocation(
// distance: distance1,
// id: carLocation['driver_id'],
// latitude: double.parse(carLocation['latitude']),
// longitude: double.parse(carLocation['longitude']),
// );
// }
// isloading = true;
update();
if (distance1 < nearestDistance) {
nearestDistance = distance1.toDouble();
// Make API request to get exact distance and duration
String apiUrl =
'${AppLink.googleMapsLink}distancematrix/json?destinations=${carLocation['latitude']},${carLocation['longitude']}&origins=${myLocation.latitude},${myLocation.longitude}&units=metric&key=${AppCredintials.mapAPIKEY}';
var response = await CRUD().getGoogleApi(link: apiUrl, payload: {});
if (response['status'] == "OK") {
var data = response;
// Extract distance and duration from the response and handle accordingly
int distance1 = data['rows'][0]['elements'][0]['distance']['value'];
distanceByPassenger =
data['rows'][0]['elements'][0]['distance']['text'];
duration1 = data['rows'][0]['elements'][0]['duration']['value'];
nearestCar = CarLocation(
distance: distance1.toDouble(),
duration: duration1.toDouble(),
id: carLocation['driver_id'],
latitude: double.parse(carLocation['latitude']),
longitude: double.parse(carLocation['longitude']),
);
// isloading = false;
durationFromDriverToPassenger =
Duration(seconds: duration1.toInt());
newTime1 = currentTime.add(durationFromDriverToPassenger);
timeFromDriverToPassenger =
newTime1.add(Duration(minutes: 2.toInt()));
durationByPassenger =
data['rows'][0]['elements'][0]['duration']['text'];
update();
}
}
if (distance1 < nearestDistance) {
nearestDistance = distance1.toDouble();
// Handle the distance and duration as needed
else {
print(
'Failed to retrieve distance and duration: ${response['status']}');
// Handle the failure case
nearestCar = CarLocation(
distance: distance1.toDouble(),
duration: duration1.toDouble(),
id: carLocation['driver_id'],
latitude: double.parse(carLocation['latitude']),
longitude: double.parse(carLocation['longitude']),
);
// isloading = false;
update();
}
}
// Handle the distance and duration as needed
else {
print(
'Failed to retrieve distance and duration: ${response['status']}');
// Handle the failure case
}
}
}
}

View File

@@ -1,12 +1,126 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:ride/constant/colors.dart';
import 'package:ride/constant/info.dart';
import 'package:ride/constant/style.dart';
import 'package:ride/views/widgets/my_scafold.dart';
import 'package:ride/views/widgets/mycircular.dart';
import 'package:flutter/animation.dart';
import '../../controller/home/captin/duration_controller .dart';
class RideCalculateDriver extends StatelessWidget {
const RideCalculateDriver({super.key});
@override
Widget build(BuildContext context) {
return MyScafolld(title: 'Ride Summary'.tr, body: [], isleading: true);
return MyScafolld(
title: 'Ride Summary'.tr,
body: const [
Center(
child: BarChartWidget(),
),
],
isleading: true);
}
}
class BarChartWidget extends StatelessWidget {
const BarChartWidget({super.key});
@override
Widget build(BuildContext context) {
final durationController = Get.put(DurationController());
return Obx(() {
final data = durationController.data;
double maxDuration = 0;
// Find the maximum duration to determine the maximum height of the bars
for (final entry in data) {
final durationInHours = entry.totalDuration.inHours.toDouble();
if (durationInHours > maxDuration) {
maxDuration = durationInHours;
}
}
return durationController.isLoading
? const Center(
child: MyCircularProgressIndicator(),
)
: Column(
children: [
Text(
'Average of Hours of ${AppInfo.appName} is ON for this month'
.tr,
style: AppStyle.title,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: Get.height * .7,
decoration: AppStyle.boxDecoration,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: data.length,
itemBuilder: (context, index) {
final entry = data[index];
final durationInHours =
entry.totalDuration.inHours.toDouble();
final dayLabel = entry.day.day.toString();
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: AnimatedBuilder(
animation: durationController.animationController,
builder: (context, child) {
final animationValue =
durationController.animationController.value;
final animatedValue =
(durationInHours / maxDuration) *
animationValue;
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Transform(
transform: Matrix4.identity()
..setEntry(3, 2,
0.001) // Apply perspective for a 3D effect
..rotateX(-0.5 *
animatedValue), // Rotate around X-axis
alignment: Alignment.bottomCenter,
child: Container(
width: 20,
height:
(durationInHours / maxDuration) * 400,
color: durationInHours > 8
? AppColor.greenColor
: AppColor.yellowColor,
child: Center(
child: Text(
durationInHours.toStringAsFixed(
0,
), // Display the duration value inside the bar
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
),
const SizedBox(height: 4),
Text(dayLabel),
],
);
},
),
);
},
),
),
),
],
);
});
}
}

View File

@@ -8,6 +8,7 @@ import 'package:ride/constant/table_names.dart';
import 'package:ride/controller/home/captin/home_captain_controller.dart';
import 'package:ride/controller/home/captin/order_request_controller.dart';
import 'package:ride/main.dart';
import 'package:ride/views/Rate/ride_calculate_driver.dart';
import 'package:ride/views/widgets/circle_container.dart';
import 'package:ride/views/widgets/elevated_btn.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
@@ -115,7 +116,7 @@ class HomeCaptain extends StatelessWidget {
Text(
' You Earn today is '.tr +
homeCaptainController
.totalToday, //Todo add here number for income
.totalMoneyToday, //Todo add here number for income
style: AppStyle.title,
),
],
@@ -131,15 +132,14 @@ class HomeCaptain extends StatelessWidget {
),
Text(
'Total Duration:'.tr +
' ${homeCaptainController.calculateTotalDuration()} seconds',
' ${homeCaptainController.totalDurationToday} ',
style: const TextStyle(fontSize: 20),
),
TextButton(
onPressed: () {
// homeCaptainController.sendSMSToRecipents(
// 'hi from Sefer', ['+962798583052']);
Get.to(() => RideCalculateDriver());
},
child: const Text('send msg')),
child: const Text('Chart')),
const Wrap(
children: <Widget>[
Icon(AntDesign.facebook_square),

View File

@@ -176,7 +176,8 @@ class CreditCardWidget extends StatelessWidget {
inputFormatters: [DigitObscuringFormatter()],
validator: (value) {
if (value!.isEmpty || value.length != 16) {
return 'Please enter a valid 16-digit card number';
return 'Please enter a valid 16-digit card number'
.tr;
}
return null;
},

View File

@@ -232,11 +232,11 @@ class EducationDegreePicker extends StatelessWidget {
final ProfileController controller = Get.put(ProfileController());
final List<String> degreeOptions = [
'High School Diploma',
'Associate Degree',
'Bachelor\'s Degree',
'Master\'s Degree',
'Doctoral Degree',
'High School Diploma'.tr,
'Associate Degree'.tr,
'Bachelor\'s Degree'.tr,
'Master\'s Degree'.tr,
'Doctoral Degree'.tr,
];
EducationDegreePicker({Key? key}) : super(key: key);

View File

@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:ride/constant/box_name.dart';
import 'package:ride/controller/firebase/firbase_messge.dart';
import 'package:ride/controller/home/captin/map_driver_controller.dart';
import 'package:ride/main.dart';
import 'package:ride/views/home/Captin/driver_map_page.dart';
import 'package:ride/views/widgets/my_scafold.dart';
@@ -10,7 +9,6 @@ import 'package:ride/views/widgets/my_scafold.dart';
import '../../constant/colors.dart';
import '../../constant/links.dart';
import '../../constant/style.dart';
import '../../constant/table_names.dart';
import '../../controller/functions/crud.dart';
import '../../controller/functions/launch.dart';
import '../../controller/home/captin/order_request_controller.dart';
@@ -28,7 +26,7 @@ class OrderRequestPage extends StatelessWidget {
final body = arguments['body'];
orderRequestController.startTimer(myList[6].toString(), body.toString());
return MyScafolld(
title: 'Order Request Page',
title: 'Order Request Page'.tr,
body: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,

View File

@@ -145,6 +145,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.8"
decimal:
dependency: transitive
description:
name: decimal
sha256: "24a261d5d5c87e86c7651c417a5dbdf8bcd7080dd592533910e8d0505a279f21"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
fake_async:
dependency: transitive
description:
@@ -214,6 +222,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_charts:
dependency: "direct main"
description:
name: flutter_charts
sha256: eb9d2bf98bfc779c1da9cf1fe80afd598094aed33e536cf04845d8f266f48c11
url: "https://pub.dev"
source: hosted
version: "0.5.2"
flutter_font_icons:
dependency: "direct main"
description:
@@ -632,6 +648,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.2.0"
logger:
dependency: transitive
description:
name: logger
sha256: "6bbb9d6f7056729537a4309bda2e74e18e5d9f14302489cc1e93f33b3fe32cac"
url: "https://pub.dev"
source: hosted
version: "2.0.2+1"
lottie:
dependency: "direct main"
description:
@@ -760,6 +784,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
rational:
dependency: transitive
description:
name: rational
sha256: ba58e9e18df9abde280e8b10051e4bce85091e41e8e7e411b6cde2e738d357cf
url: "https://pub.dev"
source: hosted
version: "2.2.2"
sanitize_html:
dependency: transitive
description:
@@ -861,6 +893,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.9.2"
tuple:
dependency: transitive
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data:
dependency: transitive
description:

View File

@@ -38,6 +38,7 @@ dependencies:
crypto: ^3.0.3
flutter_rating_bar: ^4.0.1
flutter_font_icons: ^2.2.5
flutter_charts: ^0.5.2
dev_dependencies: