new backend 29-04-2026

This commit is contained in:
Hamza-Ayed
2026-04-30 01:42:57 +03:00
parent b92db3bb39
commit 4385ef5a99
20 changed files with 796 additions and 708 deletions

View File

@@ -19,295 +19,259 @@ class RideCalculateDriver extends StatelessWidget {
return MyScafolld(
title: 'Ride Summaries'.tr,
body: [
Center(
child: GetBuilder<DurationController>(
builder: (durationController) => durationController.isLoading
? const Center(child: MyCircularProgressIndicator())
: durationController.jsonData1.isEmpty ||
durationController.jsonData2.isEmpty
? Center(
child: Text('No data yet!'.tr),
)
: ListView(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'${'Average of Hours of'.tr} ${AppInformation.appName}${' is ON for this month'.tr}${' ${durationController.jsonData1['message'][0]['day'].toString().split('-')[1]}'.tr}',
style: AppStyle.title,
textAlign: TextAlign.center,
),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
isStepLineChart: true,
spots: durationController.chartData,
isCurved: true,
color: Colors
.deepPurpleAccent, // Custom color
barWidth: 3, // Thinner line
dotData: const FlDotData(
show:
true), // Show dots on each point
belowBarData: BarAreaData(
// Add gradient fill below the line
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget: Text(
'Days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'Total Hours on month'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of Hours on days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
),
gridData: const FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: AppColor.accentColor),
left: BorderSide(
color: AppColor.accentColor),
),
),
GetBuilder<DurationController>(
builder: (durationController) {
if (durationController.isLoading) {
return const Center(child: MyCircularProgressIndicator());
}
bool hasDurations = durationController.jsonData1.isNotEmpty &&
durationController.jsonData1['message'] != null &&
(durationController.jsonData1['message'] as List).isNotEmpty;
bool hasRides = durationController.jsonData2.isNotEmpty &&
durationController.jsonData2['message'] != null &&
(durationController.jsonData2['message'] as List).isNotEmpty;
bool hasStats = durationController.monthlyList.isNotEmpty;
if (!hasDurations && !hasRides && !hasStats) {
return Center(
child: Text('No data yet!'.tr),
);
}
return ListView(
children: [
if (hasDurations) ...[
Text(
'${'Average of Hours of'.tr} ${AppInformation.appName}${' is ON for this month'.tr}${' ${durationController.jsonData1['message'][0]['day'].toString().split('-')[1]}'.tr}',
style: AppStyle.title,
textAlign: TextAlign.center,
),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
isStepLineChart: true,
spots: durationController.chartData,
isCurved: true,
color: Colors.deepPurpleAccent,
barWidth: 3,
dotData: const FlDotData(show: true),
belowBarData: BarAreaData(
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget:
Text('Days'.tr, style: AppStyle.title),
axisNameSize: 30,
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'Total Hours on month'.tr,
style: AppStyle.title),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30, showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of Hours on days'.tr,
style: AppStyle.title),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30, showTitles: true)),
),
gridData: const FlGridData(show: true),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(color: AppColor.accentColor),
left: BorderSide(color: AppColor.accentColor),
),
),
),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
spots: durationController.chartRideCount,
// isCurved: true,
color: Colors
.deepPurpleAccent, // Custom color
barWidth: 3, // Thinner line
dotData: const FlDotData(
show:
true), // Show dots on each point
belowBarData: BarAreaData(
// Add gradient fill below the line
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget: Text(
'Days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
// sideTitles: const SideTitles(
// reservedSize: 30, showTitles: true),
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'${"Total rides on month".tr} = ${durationController.jsonData2['message'][0]['totalCount'].toString()}'
.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of rides on days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
),
gridData: const FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: AppColor.accentColor),
left: BorderSide(
color: AppColor.accentColor),
),
),
),
),
),
),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
isStepLineChart: true,
spots: durationController
.chartRidePriceDriver,
isCurved: true,
isStrokeCapRound: true,
preventCurveOverShooting: true,
color: Colors
.deepPurpleAccent, // Custom color
barWidth: 3, // Thinner line
dotData: const FlDotData(
show:
true), // Show dots on each point
belowBarData: BarAreaData(
// Add gradient fill below the line
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget: Text(
'Days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
// sideTitles: const SideTitles(
// reservedSize: 30, showTitles: true),
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'${"Total budgets on month".tr} = ${durationController.jsonData2['message'][0]['totalPrice'].toString()}'
.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of budgets on days'.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30,
showTitles: true)),
),
gridData: const FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: AppColor.accentColor),
left: BorderSide(
color: AppColor.accentColor),
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: durationController.monthlyList.isEmpty
? SizedBox(
height: Get.height * .2,
child: Center(
child: Text(
"No data yet".tr,
style: AppStyle.title,
),
),
)
: DriverStatsTable(
monthlyList:
durationController.monthlyList,
)))
],
),
),
),
],
if (hasRides) ...[
const SizedBox(height: 5),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
spots: durationController.chartRideCount,
color: Colors.deepPurpleAccent,
barWidth: 3,
dotData: const FlDotData(show: true),
belowBarData: BarAreaData(
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget:
Text('Days'.tr, style: AppStyle.title),
axisNameSize: 30,
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'${"Total rides on month".tr} = ${durationController.jsonData2['message'][0]['totalCount'] ?? 0}'
.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30, showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of rides on days'.tr,
style: AppStyle.title),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30, showTitles: true)),
),
gridData: const FlGridData(show: true),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(color: AppColor.accentColor),
left: BorderSide(color: AppColor.accentColor),
),
),
),
),
),
),
const SizedBox(height: 5),
Padding(
padding: const EdgeInsets.all(6),
child: Container(
decoration: AppStyle.boxDecoration1,
height: Get.height * .4,
child: LineChart(
duration: const Duration(milliseconds: 150),
curve: Curves.ease,
LineChartData(
lineBarsData: [
LineChartBarData(
isStepLineChart: true,
spots: durationController.chartRidePriceDriver,
isCurved: true,
isStrokeCapRound: true,
preventCurveOverShooting: true,
color: Colors.deepPurpleAccent,
barWidth: 3,
dotData: const FlDotData(show: true),
belowBarData: BarAreaData(
show: true,
color: AppColor.deepPurpleAccent,
),
isStrokeJoinRound: true,
shadow: const BoxShadow(
color: AppColor.yellowColor,
blurRadius: 4,
offset: Offset(2, 2),
),
),
],
showingTooltipIndicators: const [],
titlesData: FlTitlesData(
show: true,
topTitles: AxisTitles(
axisNameWidget:
Text('Days'.tr, style: AppStyle.title),
axisNameSize: 30,
),
bottomTitles: AxisTitles(
axisNameWidget: Text(
'${"Total budgets on month".tr} = ${durationController.jsonData2['message'][0]['totalPrice'] ?? 0}'
.tr,
style: AppStyle.title,
),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30, showTitles: true)),
leftTitles: AxisTitles(
axisNameWidget: Text(
'Counts of budgets on days'.tr,
style: AppStyle.title),
axisNameSize: 30,
sideTitles: const SideTitles(
reservedSize: 30, showTitles: true)),
),
gridData: const FlGridData(show: true),
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(color: AppColor.accentColor),
left: BorderSide(color: AppColor.accentColor),
),
),
),
),
),
),
],
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: !hasStats
? SizedBox(
height: Get.height * .2,
child: Center(
child: Text(
"No statistics yet".tr,
style: AppStyle.title,
),
),
)
: DriverStatsTable(
monthlyList: durationController.monthlyList,
)))
],
);
},
)
// BarChartWidget(),
),
// BarChartWidget(),
],
isleading: true);
}

View File

@@ -296,17 +296,17 @@ class PhoneNumberScreen extends StatefulWidget {
}
class _PhoneNumberScreenState extends State<PhoneNumberScreen> {
final _phoneController = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool _isLoading = false;
String _completePhone = '';
void _submit() async {
if (_formKey.currentState!.validate()) {
setState(() => _isLoading = true);
final rawPhone = _phoneController.text.trim().replaceFirst('+', '');
final rawPhone = _completePhone.replaceFirst('+', '');
Log.print('📱 _submit rawPhone: "$rawPhone" (from _completePhone: "$_completePhone")');
final success = await PhoneAuthHelper.sendOtp(rawPhone);
if (success && mounted) {
// Get.to(() => OtpVerificationScreen(phoneNumber: rawPhone));
await PhoneAuthHelper.verifyOtp(rawPhone);
}
if (mounted) setState(() => _isLoading = false);
@@ -351,7 +351,7 @@ class _PhoneNumberScreenState extends State<PhoneNumberScreen> {
),
initialCountryCode: 'SY',
onChanged: (phone) {
_phoneController.text = phone.completeNumber;
_completePhone = phone.completeNumber;
},
validator: (phone) {
if (phone == null || phone.number.isEmpty) {

View File

@@ -184,7 +184,7 @@ class InstructionsOfRoads extends StatelessWidget {
color: AppColor.primaryColor,
shape: BoxShape.circle,
),
child: const Icon(Icons.turn_right_rounded,
child: Icon(controller.currentManeuverIcon,
color: Colors.white, size: 24),
),
const SizedBox(width: 14),
@@ -193,8 +193,8 @@ class InstructionsOfRoads extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"NEXT STEP".tr,
Text(
"${"NEXT STEP".tr} (${controller.distanceToNextStep})",
style: theme.textTheme.labelSmall?.copyWith(
color: theme.hintColor,
fontWeight: FontWeight.bold,

View File

@@ -1,21 +1,19 @@
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:sefer_driver/constant/box_name.dart';
import 'package:sefer_driver/controller/firebase/local_notification.dart';
import 'package:sefer_driver/main.dart';
import 'package:sefer_driver/views/home/Captin/driver_map_page.dart';
import 'package:sefer_driver/views/home/Captin/orderCaptin/vip_order_page.dart';
import 'package:sefer_driver/views/auth/syria/registration_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:get/get.dart';
import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart';
import 'package:sefer_driver/views/widgets/mydialoug.dart';
import '../../../../../constant/colors.dart';
import '../../../../../constant/links.dart';
import '../../../../../controller/firebase/notification_service.dart';
import '../../../../../controller/functions/crud.dart';
import '../../../../../controller/home/captin/order_request_controller.dart';
import '../../../../../controller/home/navigation/navigation_view.dart';
import '../../../../../print.dart';
import '../../../../Rate/ride_calculate_driver.dart';
@@ -78,7 +76,8 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
tooltip: 'Active Ride'.tr,
onTap: () async {
await checkForPendingOrderFromServer();
if (box.read(BoxName.rideArgumentsFromBackground) != 'failure') {
if (box.read(BoxName.rideArgumentsFromBackground) !=
'failure') {
Get.to(
() => PassengerLocationMapPage(),
arguments: box.read(BoxName.rideArgumentsFromBackground),
@@ -91,6 +90,13 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
);
}
},
onLongPress: () {
box.write(BoxName.rideArgumentsFromBackground, 'failure');
box.write(BoxName.statusDriverLocation, 'off');
box.write(BoxName.rideStatus, 'no_ride');
Log.print(box.read(BoxName.statusDriverLocation));
ctrl.update();
},
),
_Divider(context),
@@ -102,11 +108,21 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
tooltip: 'Earnings'.tr,
onTap: () {
final now = DateTime.now();
DateTime? lastTime = box.read(BoxName.lastTimeStaticThrottle);
final lastTimeRaw = box.read(BoxName.lastTimeStaticThrottle);
DateTime? lastTime;
if (lastTimeRaw != null) {
try {
lastTime = DateTime.parse(lastTimeRaw.toString());
} catch (_) {
lastTime = null;
}
}
if (lastTime == null ||
now.difference(lastTime).inMinutes >= 2) {
box.write(BoxName.lastTimeStaticThrottle, now);
box.write(
BoxName.lastTimeStaticThrottle, now.toIso8601String());
Get.to(() => RideCalculateDriver());
} else {
final left = 2 - now.difference(lastTime).inMinutes;
@@ -133,6 +149,16 @@ GetBuilder<HomeCaptainController> leftMainMenuCaptainIcons() {
onTap: () => Get.to(() => const VipOrderPage()),
),
],
// _Divider(context),
// // ── 4. Driver Registration ──────────
// _MenuIcon(
// icon: Icons.person_add_alt_1_rounded,
// color: Colors.purple.shade400,
// tooltip: 'Registration'.tr,
// onTap: () => Get.to(() => const RegistrationView()),
// ),
],
),
);

View File

@@ -5,6 +5,7 @@ import 'package:sefer_driver/constant/api_key.dart';
import '../../../../controller/functions/location_controller.dart';
import '../../../../controller/home/captin/map_driver_controller.dart';
import '../../../../controller/profile/setting_controller.dart';
class GoogleDriverMap extends StatelessWidget {
const GoogleDriverMap({
@@ -27,6 +28,11 @@ class GoogleDriverMap extends StatelessWidget {
onMapCreated: (mapController) {
controller.onMapCreated(mapController);
},
mapType: Get.isRegistered<SettingController>()
? (Get.find<SettingController>().isMapDarkMode
? IntaleqMapType.normal
: IntaleqMapType.light)
: IntaleqMapType.light,
zoomControlsEnabled: false,
initialCameraPosition: CameraPosition(
target: locationController.myLocation,
@@ -43,8 +49,8 @@ class GoogleDriverMap extends StatelessWidget {
markers: {
Marker(
markerId: MarkerId('MyLocation'.tr),
position: locationController.myLocation,
rotation: locationController.heading,
position: controller.smoothedLocation ?? locationController.myLocation,
rotation: controller.smoothedHeading,
flat: true,
anchor: const Offset(0.5, 0.5),
icon: controller.carIcon,

View File

@@ -281,7 +281,7 @@ class RideAvailableCard extends StatelessWidget {
Get.back();
// 3. تحليل الرد
var jsonResponse = jsonDecode(response);
var jsonResponse = response;
if (jsonResponse['status'] == 'success') {
// ✅ نجاح: أنت الفائز بالرحلة