This commit is contained in:
Hamza-Ayed
2024-11-03 13:39:16 +02:00
parent 3e88059166
commit 5919554eaa
20 changed files with 1188 additions and 24 deletions

View File

@@ -1,29 +1,32 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application android:label="sefer_admin1" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> <application android:label="sefer_admin1" android:name="${applicationName}"
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> android:icon="@mipmap/ic_launcher">
<!-- Specifies an Android theme to apply to this Activity as soon as <activity android:name=".MainActivity" android:exported="true"
the Android process has started. This theme is visible to the user android:launchMode="singleTop" android:theme="@style/LaunchTheme"
while the Flutter UI initializes. After that, this theme continues android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
to determine the Window background behind the Flutter UI. --> android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> <meta-data android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <!-- Move UCropActivity definition outside the MainActivity block -->
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
<meta-data android:name="flutterEmbedding" android:value="2" /> <meta-data android:name="flutterEmbedding" android:value="2" />
</application> </application>
<!-- Required to query activities that can process text, see: https://developer.android.com/training/package-visibility?hl=en and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries> <queries>
<intent> <intent>
<action android:name="android.intent.action.PROCESS_TEXT"/> <action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain"/> <data android:mimeType="text/plain" />
</intent> </intent>
</queries> </queries>
</manifest> </manifest>

View File

@@ -7,12 +7,19 @@ PODS:
- AppAuth/Core - AppAuth/Core
- Firebase/CoreOnly (10.25.0): - Firebase/CoreOnly (10.25.0):
- FirebaseCore (= 10.25.0) - FirebaseCore (= 10.25.0)
- Firebase/Crashlytics (10.25.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 10.25.0)
- Firebase/Messaging (10.25.0): - Firebase/Messaging (10.25.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseMessaging (~> 10.25.0) - FirebaseMessaging (~> 10.25.0)
- firebase_core (2.32.0): - firebase_core (2.32.0):
- Firebase/CoreOnly (= 10.25.0) - Firebase/CoreOnly (= 10.25.0)
- Flutter - Flutter
- firebase_crashlytics (3.5.7):
- Firebase/Crashlytics (= 10.25.0)
- firebase_core
- Flutter
- firebase_messaging (14.9.4): - firebase_messaging (14.9.4):
- Firebase/Messaging (= 10.25.0) - Firebase/Messaging (= 10.25.0)
- firebase_core - firebase_core
@@ -21,8 +28,19 @@ PODS:
- FirebaseCoreInternal (~> 10.0) - FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.12) - GoogleUtilities/Environment (~> 7.12)
- GoogleUtilities/Logger (~> 7.12) - GoogleUtilities/Logger (~> 7.12)
- FirebaseCoreExtension (10.29.0):
- FirebaseCore (~> 10.0)
- FirebaseCoreInternal (10.27.0): - FirebaseCoreInternal (10.27.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)" - "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseCrashlytics (10.25.0):
- FirebaseCore (~> 10.5)
- FirebaseInstallations (~> 10.0)
- FirebaseRemoteConfigInterop (~> 10.23)
- FirebaseSessions (~> 10.5)
- GoogleDataTransport (~> 9.2)
- GoogleUtilities/Environment (~> 7.8)
- nanopb (< 2.30911.0, >= 2.30908.0)
- PromisesObjC (~> 2.1)
- FirebaseInstallations (10.27.0): - FirebaseInstallations (10.27.0):
- FirebaseCore (~> 10.0) - FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/Environment (~> 7.8)
@@ -37,7 +55,22 @@ PODS:
- GoogleUtilities/Reachability (~> 7.8) - GoogleUtilities/Reachability (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8) - GoogleUtilities/UserDefaults (~> 7.8)
- nanopb (< 2.30911.0, >= 2.30908.0) - nanopb (< 2.30911.0, >= 2.30908.0)
- FirebaseRemoteConfigInterop (10.29.0)
- FirebaseSessions (10.29.0):
- FirebaseCore (~> 10.5)
- FirebaseCoreExtension (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleDataTransport (~> 9.2)
- GoogleUtilities/Environment (~> 7.13)
- GoogleUtilities/UserDefaults (~> 7.13)
- nanopb (< 2.30911.0, >= 2.30908.0)
- PromisesSwift (~> 2.1)
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_image_compress_common (1.0.0):
- Flutter
- Mantle
- SDWebImage
- SDWebImageWebPCoder
- flutter_secure_storage (6.0.0): - flutter_secure_storage (6.0.0):
- Flutter - Flutter
- google_sign_in_ios (0.0.1): - google_sign_in_ios (0.0.1):
@@ -92,8 +125,23 @@ PODS:
- TOCropViewController (~> 2.7.4) - TOCropViewController (~> 2.7.4)
- image_picker_ios (0.0.1): - image_picker_ios (0.0.1):
- Flutter - Flutter
- libwebp (1.3.2):
- libwebp/demux (= 1.3.2)
- libwebp/mux (= 1.3.2)
- libwebp/sharpyuv (= 1.3.2)
- libwebp/webp (= 1.3.2)
- libwebp/demux (1.3.2):
- libwebp/webp
- libwebp/mux (1.3.2):
- libwebp/demux
- libwebp/sharpyuv (1.3.2)
- libwebp/webp (1.3.2):
- libwebp/sharpyuv
- local_auth_darwin (0.0.1): - local_auth_darwin (0.0.1):
- Flutter - Flutter
- Mantle (2.2.0):
- Mantle/extobjc (= 2.2.0)
- Mantle/extobjc (2.2.0)
- nanopb (2.30910.0): - nanopb (2.30910.0):
- nanopb/decode (= 2.30910.0) - nanopb/decode (= 2.30910.0)
- nanopb/encode (= 2.30910.0) - nanopb/encode (= 2.30910.0)
@@ -103,6 +151,14 @@ PODS:
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- PromisesObjC (2.4.0) - PromisesObjC (2.4.0)
- PromisesSwift (2.4.0):
- PromisesObjC (= 2.4.0)
- SDWebImage (5.19.7):
- SDWebImage/Core (= 5.19.7)
- SDWebImage/Core (5.19.7)
- SDWebImageWebPCoder (0.14.6):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.17)
- sqflite (0.0.3): - sqflite (0.0.3):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
@@ -112,8 +168,10 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`) - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`)
- image_cropper (from `.symlinks/plugins/image_cropper/ios`) - image_cropper (from `.symlinks/plugins/image_cropper/ios`)
@@ -128,25 +186,38 @@ SPEC REPOS:
- AppAuth - AppAuth
- Firebase - Firebase
- FirebaseCore - FirebaseCore
- FirebaseCoreExtension
- FirebaseCoreInternal - FirebaseCoreInternal
- FirebaseCrashlytics
- FirebaseInstallations - FirebaseInstallations
- FirebaseMessaging - FirebaseMessaging
- FirebaseRemoteConfigInterop
- FirebaseSessions
- GoogleDataTransport - GoogleDataTransport
- GoogleSignIn - GoogleSignIn
- GoogleUtilities - GoogleUtilities
- GTMAppAuth - GTMAppAuth
- GTMSessionFetcher - GTMSessionFetcher
- libwebp
- Mantle
- nanopb - nanopb
- PromisesObjC - PromisesObjC
- PromisesSwift
- SDWebImage
- SDWebImageWebPCoder
- TOCropViewController - TOCropViewController
EXTERNAL SOURCES: EXTERNAL SOURCES:
firebase_core: firebase_core:
:path: ".symlinks/plugins/firebase_core/ios" :path: ".symlinks/plugins/firebase_core/ios"
firebase_crashlytics:
:path: ".symlinks/plugins/firebase_crashlytics/ios"
firebase_messaging: firebase_messaging:
:path: ".symlinks/plugins/firebase_messaging/ios" :path: ".symlinks/plugins/firebase_messaging/ios"
Flutter: Flutter:
:path: Flutter :path: Flutter
flutter_image_compress_common:
:path: ".symlinks/plugins/flutter_image_compress_common/ios"
flutter_secure_storage: flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios" :path: ".symlinks/plugins/flutter_secure_storage/ios"
google_sign_in_ios: google_sign_in_ios:
@@ -168,12 +239,18 @@ SPEC CHECKSUMS:
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
Firebase: 0312a2352584f782ea56f66d91606891d4607f06 Firebase: 0312a2352584f782ea56f66d91606891d4607f06
firebase_core: a626d00494efa398e7c54f25f1454a64c8abf197 firebase_core: a626d00494efa398e7c54f25f1454a64c8abf197
firebase_crashlytics: 17e856fabec68d993662abaf2f6fe2413f0abece
firebase_messaging: 06391e8f35dc65a00c56580266285263d2861f10 firebase_messaging: 06391e8f35dc65a00c56580266285263d2861f10
FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483 FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483
FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f
FirebaseCoreInternal: 4b297a2d56063dbea2c1d0d04222d44a8d058862 FirebaseCoreInternal: 4b297a2d56063dbea2c1d0d04222d44a8d058862
FirebaseCrashlytics: 4b96efb0ce73b38b2a85e8b8bd1bd8f63f09d015
FirebaseInstallations: 766dabca09fd94aef922538aaf144cc4a6fb6869 FirebaseInstallations: 766dabca09fd94aef922538aaf144cc4a6fb6869
FirebaseMessaging: 88950ba9485052891ebe26f6c43a52bb62248952 FirebaseMessaging: 88950ba9485052891ebe26f6c43a52bb62248952
FirebaseRemoteConfigInterop: 6efda51fb5e2f15b16585197e26eaa09574e8a4d
FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12 flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
google_sign_in_ios: 07375bfbf2620bc93a602c0e27160d6afc6ead38 google_sign_in_ios: 07375bfbf2620bc93a602c0e27160d6afc6ead38
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
@@ -183,10 +260,15 @@ SPEC CHECKSUMS:
GTMSessionFetcher: 8000756fc1c19d2e5697b90311f7832d2e33f6cd GTMSessionFetcher: 8000756fc1c19d2e5697b90311f7832d2e33f6cd
image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
local_auth_darwin: 4d56c90c2683319835a61274b57620df9c4520ab local_auth_darwin: 4d56c90c2683319835a61274b57620df9c4520ab
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
nanopb: 438bc412db1928dac798aa6fd75726007be04262 nanopb: 438bc412db1928dac798aa6fd75726007be04262
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654 TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe

View File

@@ -104,6 +104,7 @@ class AppLink {
"$ride/notificationPassenger/get.php"; "$ride/notificationPassenger/get.php";
static String updateNotificationPassenger = static String updateNotificationPassenger =
"$ride/notificationPassenger/update.php"; "$ride/notificationPassenger/update.php";
//-----------------Driver NotificationCaptain------------------ //-----------------Driver NotificationCaptain------------------
static String addNotificationCaptain = "$ride/notificationCaptain/add.php"; static String addNotificationCaptain = "$ride/notificationCaptain/add.php";
static String addWaitingRide = "$ride/notificationCaptain/addWaitingRide.php"; static String addWaitingRide = "$ride/notificationCaptain/addWaitingRide.php";
@@ -229,6 +230,9 @@ class AppLink {
static String getPassengerbyEmail = "$server/Admin/getPassengerbyEmail.php"; static String getPassengerbyEmail = "$server/Admin/getPassengerbyEmail.php";
static String addAdminUser = "$server/Admin/adminUser/add.php"; static String addAdminUser = "$server/Admin/adminUser/add.php";
static String getdashbord = "$server/Admin/dashbord.php"; static String getdashbord = "$server/Admin/dashbord.php";
static String getEmployee = "$server/Admin/employee/get.php";
static String getBestDriver = "$server/Admin/driver/getBestDriver.php";
static String addEmployee = "$server/Admin/employee/add.php";
static String getdashbordPayment = "$server/Admin/dashbordPayment.php"; static String getdashbordPayment = "$server/Admin/dashbordPayment.php";
static String getAdminUser = "$server/Admin/adminUser/get.php"; static String getAdminUser = "$server/Admin/adminUser/get.php";
static String getCaptainDetailsByEmailOrIDOrPhone = static String getCaptainDetailsByEmailOrIDOrPhone =
@@ -263,6 +267,8 @@ class AppLink {
static String addNotesDriver = "$serviceApp/addNotesDriver.php"; static String addNotesDriver = "$serviceApp/addNotesDriver.php";
static String getCarPlateNotEdit = "$serviceApp/getCarPlateNotEdit.php"; static String getCarPlateNotEdit = "$serviceApp/getCarPlateNotEdit.php";
static String addNotesPassenger = "$serviceApp/addNotesPassenger.php"; static String addNotesPassenger = "$serviceApp/addNotesPassenger.php";
static String getPackages = "$serviceApp/getPackages.php";
static String updatePackages = "$serviceApp/updatePackages.php";
////// //////
static String sendSms = "https://sms.kazumi.me/api/sms/send-sms"; static String sendSms = "https://sms.kazumi.me/api/sms/send-sms";
static String senddlr = "https://sms.kazumi.me/api/sms/send-dlr"; static String senddlr = "https://sms.kazumi.me/api/sms/send-dlr";

View File

@@ -20,6 +20,7 @@ class StaticController extends GetxController {
var chartDataEmployeeMaryam; var chartDataEmployeeMaryam;
var chartDataEmployeeRawda; var chartDataEmployeeRawda;
var chartDataEmployeeMena; var chartDataEmployeeMena;
var chartDataEmployeeSefer4;
var chartDataDriversMatchingNotes; var chartDataDriversMatchingNotes;
bool isLoading = false; bool isLoading = false;
String totalMonthlyPassengers = ''; String totalMonthlyPassengers = '';
@@ -111,6 +112,7 @@ class StaticController extends GetxController {
List<FlSpot> chartDataMaryam = []; List<FlSpot> chartDataMaryam = [];
List<FlSpot> chartDataRawda = []; List<FlSpot> chartDataRawda = [];
List<FlSpot> chartDataMena = []; List<FlSpot> chartDataMena = [];
List<FlSpot> chartDataSefer4 = [];
for (int day = 1; day <= DateTime.now().day; day++) { for (int day = 1; day <= DateTime.now().day; day++) {
chartDataMaryam.add(FlSpot( chartDataMaryam.add(FlSpot(
@@ -124,10 +126,10 @@ class StaticController extends GetxController {
0)); 0));
chartDataRawda.add(FlSpot( chartDataRawda.add(FlSpot(
day.toDouble(), day.toDouble(),
employeeDataMap['rawda'] employeeDataMap['yasmine']
?.firstWhere((e) => e.day == day, ?.firstWhere((e) => e.day == day,
orElse: () => MonthlyEmployeeData( orElse: () => MonthlyEmployeeData(
day: day, totalEmployees: 0, name: 'rawda')) day: day, totalEmployees: 0, name: 'yasmine'))
.totalEmployees .totalEmployees
.toDouble() ?? .toDouble() ??
0)); 0));
@@ -140,12 +142,22 @@ class StaticController extends GetxController {
.totalEmployees .totalEmployees
.toDouble() ?? .toDouble() ??
0)); 0));
chartDataSefer4.add(FlSpot(
day.toDouble(),
employeeDataMap['ashjan']
?.firstWhere((e) => e.day == day,
orElse: () => MonthlyEmployeeData(
day: day, totalEmployees: 0, name: 'ashjan'))
.totalEmployees
.toDouble() ??
0));
} }
// Combine spots into a single list if needed or keep them separate // Combine spots into a single list if needed or keep them separate
chartDataEmployeeMaryam = chartDataMaryam; chartDataEmployeeMaryam = chartDataMaryam;
chartDataEmployeeRawda = chartDataRawda; chartDataEmployeeRawda = chartDataRawda;
chartDataEmployeeMena = chartDataMena; chartDataEmployeeMena = chartDataMena;
chartDataEmployeeSefer4 = chartDataSefer4;
update(); update();
} }

View File

@@ -0,0 +1,27 @@
import 'dart:convert';
import 'package:get/get.dart';
import '../../constant/colors.dart';
import '../../constant/links.dart';
import '../functions/crud.dart';
class Driverthebest extends GetxController {
bool isLoading = false;
List driver = [];
getBestDriver() async {
var res = await CRUD().get(link: AppLink.getBestDriver, payload: {});
if (res != 'failure') {
driver = jsonDecode(res)['message'];
update();
} else {
Get.snackbar('error', '', backgroundColor: AppColor.redColor);
}
}
@override
void onInit() {
getBestDriver();
super.onInit();
}
}

View File

@@ -0,0 +1,76 @@
import 'dart:convert';
import 'dart:math';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:sefer_admin1/constant/colors.dart';
import 'package:sefer_admin1/constant/links.dart';
import 'package:sefer_admin1/controller/functions/crud.dart';
class EmployeeController extends GetxController {
List employee = [];
final name = TextEditingController();
final education = TextEditingController();
final site = TextEditingController();
final phone = TextEditingController();
final status = TextEditingController();
final formKey = GlobalKey<FormState>();
fetchEmployee() async {
var res = await CRUD().get(link: AppLink.getEmployee, payload: {});
if (res != 'failure') {
employee = jsonDecode(res)['message'];
update();
} else {
Get.snackbar('error', '', backgroundColor: AppColor.redColor);
}
}
late String id;
String generateRandomId(int length) {
const String chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
Random random = Random();
return String.fromCharCodes(Iterable.generate(
length,
(_) => chars.codeUnitAt(random.nextInt(chars.length)),
));
}
addEmployee() async {
// Create the payload with the employee data
var res = await CRUD().post(link: AppLink.addEmployee, payload: {
"id": id,
"name": name.text,
"education": education.text,
"site": site.text,
"phone": phone.text,
"status": status.text,
});
// Check the response from the API
if (res != 'failure') {
// You can handle the success case here, such as showing a success message
Get.back();
Get.snackbar('Success', 'Employee added successfully',
backgroundColor: AppColor.greenColor);
name.clear();
education.clear();
site.clear();
phone.clear();
status.clear();
fetchEmployee();
} else {
// Handle the error case by showing a snackbar with an error message
Get.snackbar('Error', 'Failed to add employee',
backgroundColor: AppColor.redColor);
}
}
@override
void onInit() {
fetchEmployee();
super.onInit();
}
}

View File

@@ -296,8 +296,9 @@ class CRUD {
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}', 'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
}, },
); );
Log.print('payload: ${payload}');
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
Log.print('jsonData: ${jsonData}');
if (response.statusCode == 200) { if (response.statusCode == 200) {
if (jsonData['status'] == 'success') { if (jsonData['status'] == 'success') {

View File

@@ -7,6 +7,14 @@ void showInBrowser(String url) async {
} else {} } else {}
} }
Future<void> makePhoneCall(String phoneNumber) async {
final Uri launchUri = Uri(
scheme: 'tel',
path: phoneNumber,
);
await launchUrl(launchUri);
}
void launchCommunication( void launchCommunication(
String method, String contactInfo, String message) async { String method, String contactInfo, String message) async {
String url; String url;

View File

@@ -0,0 +1,446 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:image/image.dart' as img;
import 'package:path_provider/path_provider.dart' as path_provider;
import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../main.dart';
import '../../print.dart';
class ImageController extends GetxController {
File? myImage;
bool isloading = false;
CroppedFile? croppedFile;
final picker = ImagePicker();
var image;
Future<img.Image> detectAndCropDocument(File imageFile) async {
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) throw Exception('Unable to decode image');
int left = image.width, top = image.height, right = 0, bottom = 0;
// Threshold for considering a pixel as part of the document (adjust as needed)
const int threshold = 240;
for (int y = 0; y < image.height; y++) {
for (int x = 0; x < image.width; x++) {
final pixel = image.getPixel(x, y);
final luminance = img.getLuminance(pixel);
if (luminance < threshold) {
left = x < left ? x : left;
top = y < top ? y : top;
right = x > right ? x : right;
bottom = y > bottom ? y : bottom;
}
}
}
// Add a small padding
left = (left - 5).clamp(0, image.width);
top = (top - 5).clamp(0, image.height);
right = (right + 5).clamp(0, image.width);
bottom = (bottom + 5).clamp(0, image.height);
return img.copyCrop(image,
x: left, y: top, width: right - left, height: bottom - top);
}
Future<File> rotateImageIfNeeded(File imageFile) async {
img.Image croppedDoc = await detectAndCropDocument(imageFile);
// Check if the document is in portrait orientation
bool isPortrait = croppedDoc.height > croppedDoc.width;
img.Image processedImage;
if (isPortrait) {
// Rotate the image by 90 degrees clockwise
processedImage = img.copyRotate(croppedDoc, angle: 90);
} else {
processedImage = croppedDoc;
}
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the processed image file
File processedFile = File('$tempPath/processed_image.jpg');
await processedFile.writeAsBytes(img.encodeJpg(processedImage));
return processedFile;
}
Future<File> rotateImage(File imageFile) async {
// Read the image file
img.Image? image = img.decodeImage(await imageFile.readAsBytes());
if (image == null) return imageFile;
// Rotate the image by 90 degrees clockwise
img.Image rotatedImage = img.copyRotate(image, angle: 90);
// Get temporary directory
final tempDir = await path_provider.getTemporaryDirectory();
final tempPath = tempDir.path;
// Create the rotated image file
File rotatedFile = File('$tempPath/rotated_image.jpg');
await rotatedFile.writeAsBytes(img.encodeJpg(rotatedImage));
return rotatedFile;
}
choosImage(String link, String imageType, String id) async {
try {
final pickedImage = await picker.pickImage(
source: ImageSource.camera,
preferredCameraDevice: CameraDevice.rear,
);
if (pickedImage == null) return;
image = File(pickedImage.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false,
),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
if (croppedFile == null) return;
myImage = File(croppedFile!.path);
isloading = true;
update();
// Rotate the compressed image
File processedImage = await rotateImageIfNeeded(File(croppedFile!.path));
File compressedImage = await compressImage(processedImage);
print('link =$link');
Log.print('link: ${link}');
await uploadImage(
compressedImage,
{
'driverID': id,
'imageType': imageType,
},
link,
);
} catch (e) {
print('Error in choosImage: $e');
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.primaryColor);
} finally {
isloading = false;
update();
}
}
// choosFaceFromDriverLicense(String link, String imageType) async {
// final pickedImage = await picker.pickImage(
// source: ImageSource.camera,
// preferredCameraDevice: CameraDevice.rear,
// );
// if (pickedImage == null) return;
// image = File(pickedImage.path);
// File? processedImage;
// // For face images, use face detection and cropping
// processedImage = await detectAndCropFace(image!);
// if (processedImage == null) {
// Get.snackbar('Face Detection Failed', 'No face detected in the image.');
// return;
// }
// isloading = true;
// update();
// File compressedImage = await compressImage(processedImage);
// try {
// await uploadImage(
// compressedImage,
// {
// 'driverID': box.read(BoxName.driverID).toString(),
// 'imageType': imageType
// },
// link,
// );
// } catch (e) {
// Get.snackbar('Image Upload Failed'.tr, e.toString(),
// backgroundColor: AppColor.redColor);
// } finally {
// isloading = false;
// update();
// }
// }
choosFace(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.camera,
preferredCameraDevice: CameraDevice.front,
);
if (pickedImage != null) {
image = File(pickedImage.path);
isloading = true;
update();
// Compress the image
File compressedImage = await compressImage(File(pickedImage.path));
// Save the picked image directly
// File savedImage = File(pickedImage.path);
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
}
uploadImage(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link),
);
var length = await file.length();
var stream = http.ByteStream(file.openRead());
var multipartFile = http.MultipartFile(
'image',
stream,
length,
filename: basename(file.path),
);
request.headers.addAll({
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
});
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
Log.print('jsonDecode(res.body): ${jsonDecode(res.body)}');
Get.snackbar('title', 'message', backgroundColor: AppColor.greenColor);
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
choosImagePicture(String link, String imageType) async {
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
// preferredCameraDevice: CameraDevice.rear,
// maxHeight: Get.height * .3,
// maxWidth: Get.width * .9,
// imageQuality: 100,
);
image = File(pickedImage!.path);
croppedFile = await ImageCropper().cropImage(
sourcePath: image!.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper'.tr,
toolbarColor: AppColor.blueColor,
toolbarWidgetColor: AppColor.yellowColor,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper'.tr,
),
],
);
myImage = File(pickedImage.path);
isloading = true;
update();
// Save the cropped image
// File savedCroppedImage = File(croppedFile!.path);
File compressedImage = await compressImage(File(croppedFile!.path));
print('link =$link');
try {
await uploadImage(
compressedImage,
{
'driverID':
box.read(BoxName.driverID) ?? box.read(BoxName.passengerID),
'imageType': imageType
},
link,
);
} catch (e) {
Get.snackbar('Image Upload Failed'.tr, e.toString(),
backgroundColor: AppColor.redColor);
} finally {
isloading = false;
update();
}
}
uploadImagePicture(File file, Map data, String link) async {
var request = http.MultipartRequest(
'POST',
Uri.parse(link), //'https://ride.mobile-app.store/uploadImage1.php'
);
var length = await file.length();
var stream = http.ByteStream(file.openRead());
var multipartFile = http.MultipartFile(
'image',
stream,
length,
filename: basename(file.path),
);
request.headers.addAll({
'Authorization':
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials.toString()))}',
});
// Set the file name to the driverID
request.files.add(
http.MultipartFile(
'image',
stream,
length,
filename: '${box.read(BoxName.driverID)}.jpg',
),
);
data.forEach((key, value) {
request.fields[key] = value;
});
var myrequest = await request.send();
var res = await http.Response.fromStream(myrequest);
if (res.statusCode == 200) {
return jsonDecode(res.body);
} else {
throw Exception(
'Failed to upload image: ${res.statusCode} - ${res.body}');
}
}
}
Future<File> compressImage(File file) async {
final dir = await path_provider.getTemporaryDirectory();
final targetPath = "${dir.absolute.path}/temp.jpg";
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path,
targetPath,
quality: 70,
minWidth: 1024,
minHeight: 1024,
);
return File(result!.path);
}
// Future<File> detectAndCropFace(File imageFile) async {
// final inputImage = InputImage.fromFilePath(imageFile.path);
// final options = FaceDetectorOptions(
// enableClassification: false,
// enableLandmarks: false,
// enableTracking: false,
// minFaceSize: 0.15,
// performanceMode: FaceDetectorMode.accurate,
// );
// final faceDetector = FaceDetector(options: options);
// try {
// final List<Face> faces = await faceDetector.processImage(inputImage);
// final image = img.decodeImage(await imageFile.readAsBytes());
// if (image == null) throw Exception('Unable to decode image');
// int left, top, width, height;
// if (faces.isNotEmpty) {
// // Face detected, crop around the face
// final face = faces[0];
// double padding = 0.2; // 20% padding
// int paddingX = (face.boundingBox.width * padding).round();
// int paddingY = (face.boundingBox.height * padding).round();
// left = (face.boundingBox.left - paddingX).round();
// top = (face.boundingBox.top - paddingY).round();
// width = (face.boundingBox.width + 2 * paddingX).round();
// height = (face.boundingBox.height + 2 * paddingY).round();
// } else {
// // No face detected, crop the center of the image
// int size = min(image.width, image.height);
// left = (image.width - size) ~/ 2;
// top = (image.height - size) ~/ 2;
// width = size;
// height = size;
// }
// // Ensure dimensions are within image bounds
// left = left.clamp(0, image.width - 1);
// top = top.clamp(0, image.height - 1);
// width = width.clamp(1, image.width - left);
// height = height.clamp(1, image.height - top);
// final croppedImage =
// img.copyCrop(image, x: left, y: top, width: width, height: height);
// // Save the cropped image
// final tempDir = await path_provider.getTemporaryDirectory();
// final tempPath = tempDir.path;
// final croppedFile = File('$tempPath/cropped_image.jpg');
// await croppedFile.writeAsBytes(img.encodeJpg(croppedImage, quality: 100));
// return croppedFile;
// } finally {
// faceDetector.close();
// }
// }

View File

@@ -0,0 +1,64 @@
import 'dart:convert';
import 'package:get/get.dart';
import 'package:sefer_admin1/constant/colors.dart';
import '../../constant/links.dart';
import '../firebase/firbase_messge.dart';
import 'crud.dart';
class WalletController extends GetxController {
String paymentToken = '';
Future<String> generateTokenDriver(String amount, driverID) async {
var res = await CRUD().post(link: AppLink.addPaymentTokenDriver, payload: {
'driverID': driverID.toString(),
'amount': amount.toString(),
});
var d = jsonDecode(res);
return d['message'];
}
addPaymentToDriver(String amount, driverID, token) async {
paymentToken = await generateTokenDriver(amount.toString(), driverID);
var res = await CRUD().post(link: AppLink.addDrivePayment, payload: {
'rideId': 'gift$driverID',
'amount': amount,
'payment_method': 'visaRide',
'passengerID': 'passengerId',
'token': paymentToken,
'driverID': driverID.toString(),
});
if (res != 'failure') {
FirebaseMessagesController().sendNotificationToAnyWithoutData(
'you have gift from SEFER'.tr,
'',
token, // Access token correctly
'ding.wav',
);
Get.snackbar('success', 'addPaymentToDriver',
backgroundColor: AppColor.greenColor);
} else {
Get.snackbar('error', 'addPaymentToDriver',
backgroundColor: AppColor.redColor);
}
}
Future addSeferWallet(String point, driverID) async {
var amount = (int.parse(point) * -1).toStringAsFixed(0);
var seferToken = await generateTokenDriver(amount, driverID);
var res = await CRUD().post(link: AppLink.addSeferWallet, payload: {
'amount': amount.toString(),
'paymentMethod': 'visaRide',
'passengerId': 'gift$driverID',
'token': seferToken,
'driverId': driverID.toString(),
});
if (res != 'failure') {
Get.snackbar('success', 'addSeferWallet',
backgroundColor: AppColor.greenColor);
} else {
Get.snackbar('error', 'addSeferWallet',
backgroundColor: AppColor.redColor);
}
}
}

View File

@@ -74,7 +74,8 @@ class NotificationController extends GetxController {
"title": title.text, "title": title.text,
"body": body.text, "body": body.text,
}); });
Log.print('res: ${res}'); Log.print(
'res: ${res}for ${box.read(BoxName.tokensDrivers)['message'][i]['id']}');
// Log.print('tokensDriver[i]: ${tokensDriver[i]}'); // Log.print('tokensDriver[i]: ${tokensDriver[i]}');
Future.delayed(const Duration(microseconds: 50)); Future.delayed(const Duration(microseconds: 50));
@@ -138,7 +139,8 @@ class NotificationController extends GetxController {
if (formKey.currentState!.validate()) { if (formKey.currentState!.validate()) {
var res = await CRUD() var res = await CRUD()
.post(link: AppLink.addNotificationPassenger, payload: { .post(link: AppLink.addNotificationPassenger, payload: {
"passenger_id": tokensPassengersData[i]['id'].toString(), "passenger_id":
tokensPassengersData[i]['passengerID'].toString(),
"title": title.text, "title": title.text,
"body": body.text, "body": body.text,
}); });

View File

@@ -8,6 +8,7 @@ import 'package:sefer_admin1/controller/admin/static_controller.dart';
import 'package:sefer_admin1/controller/notification_controller.dart'; import 'package:sefer_admin1/controller/notification_controller.dart';
import 'package:sefer_admin1/views/admin/captain/drivers_cant_registe.dart'; import 'package:sefer_admin1/views/admin/captain/drivers_cant_registe.dart';
import 'package:sefer_admin1/views/admin/captain/register_captain.dart'; import 'package:sefer_admin1/views/admin/captain/register_captain.dart';
import 'package:sefer_admin1/views/admin/employee/employee_page.dart';
import 'package:sefer_admin1/views/widgets/elevated_btn.dart'; import 'package:sefer_admin1/views/widgets/elevated_btn.dart';
import 'package:sefer_admin1/views/widgets/my_textField.dart'; import 'package:sefer_admin1/views/widgets/my_textField.dart';
import 'package:sefer_admin1/views/widgets/mycircular.dart'; import 'package:sefer_admin1/views/widgets/mycircular.dart';
@@ -19,6 +20,8 @@ import '../../controller/functions/gemeni.dart';
import '../../print.dart'; import '../../print.dart';
import '../widgets/my_scafold.dart'; import '../widgets/my_scafold.dart';
import 'captain/captain.dart'; import 'captain/captain.dart';
import 'drivers/driver_the_best.dart';
import 'packages.dart';
import 'passenger/passenger.dart'; import 'passenger/passenger.dart';
import 'rides/rides.dart'; import 'rides/rides.dart';
import 'static/static.dart'; import 'static/static.dart';
@@ -410,7 +413,25 @@ class AdminHomePage extends StatelessWidget {
onPressed: () async { onPressed: () async {
await Get.put(RegisterCaptainController()) await Get.put(RegisterCaptainController())
.getDriverNotCompleteRegistration(); .getDriverNotCompleteRegistration();
Get.to(() => DriversCantRegister()); Get.to(() => const DriversCantRegister());
},
),
AdminWidgetsDashBoard(
title: 'update packages'.tr,
onPressed: () async {
Get.to(() => PackageUpdateScreen());
},
),
AdminWidgetsDashBoard(
title: 'Employee'.tr,
onPressed: () async {
Get.to(() => EmployeePage());
},
),
AdminWidgetsDashBoard(
title: 'Drivers the best'.tr,
onPressed: () async {
Get.to(() => DriverTheBest());
}, },
), ),

View File

@@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sefer_admin1/controller/functions/wallet.dart';
import 'package:sefer_admin1/views/admin/wallet/wallet.dart';
import 'package:sefer_admin1/views/widgets/my_scafold.dart';
import '../../../controller/drivers/driverthebest.dart';
class DriverTheBest extends StatelessWidget {
const DriverTheBest({super.key});
@override
Widget build(BuildContext context) {
Get.put(Driverthebest());
return MyScafolld(
title: 'Best Drivers'.tr,
body: [
GetBuilder<Driverthebest>(builder: (driverthebest) {
return driverthebest.driver.isNotEmpty
? ListView.builder(
itemCount: driverthebest.driver.length,
itemBuilder: (context, index) {
final driver = driverthebest.driver[index];
return ListTile(
leading: CircleAvatar(
child: Text(
((driver['driver_count'] * 5) / 3600)
.toStringAsFixed(0),
),
),
title: Text(driver['name_arabic'] ?? 'Unknown Name'),
subtitle: Text('Phone: ${driver['phone'] ?? 'N/A'}'),
trailing: IconButton(
onPressed: () async {
Get.defaultDialog(
title:
'are you sure to pay to this driver gift'.tr,
middleText: '',
onConfirm: () async {
final wallet = Get.put(WalletController());
await wallet.addPaymentToDriver('200',
driver['id'].toString(), driver['token']);
await wallet.addSeferWallet(
'200', driver['id'].toString());
},
onCancel: () => Get.back());
},
icon: const Icon(Icons.wallet_giftcard_rounded),
),
);
},
)
: const Center(
child: Text('No drivers available.'),
);
})
],
isleading: true,
);
}
}

View File

@@ -0,0 +1,185 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sefer_admin1/constant/colors.dart';
import 'package:sefer_admin1/constant/style.dart';
import 'package:sefer_admin1/controller/employee_controller/employee_controller.dart';
import 'package:sefer_admin1/controller/functions/launch.dart';
import 'package:sefer_admin1/views/widgets/elevated_btn.dart';
import 'package:sefer_admin1/views/widgets/my_scafold.dart';
import 'package:sefer_admin1/views/widgets/my_textField.dart';
import '../../../constant/links.dart';
import '../../../controller/functions/upload_image copy.dart';
class EmployeePage extends StatelessWidget {
const EmployeePage({super.key});
@override
Widget build(BuildContext context) {
Get.put(EmployeeController());
return GetBuilder<EmployeeController>(builder: (employeeController) {
return Scaffold(
appBar: AppBar(
title: Text('Employee Page'.tr),
),
body: ListView.builder(
itemCount: employeeController
.employee.length, // Set the item count based on the employee list
itemBuilder: (context, index) {
// Get the employee data for the current index
var employee = employeeController.employee[index];
// Return a widget to display the employee information
return Padding(
padding: const EdgeInsets.all(3.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: ListTile(
trailing: IconButton(
onPressed: () {
Get.to(() => EmployeeDetails(
index: index,
));
},
icon: Icon(
Icons.shop_two,
color: employee['status'].toString().contains('ممتاز')
? AppColor.greenColor
: AppColor.accentColor,
),
),
title: Column(
children: [
Text(employee['name']),
Text(
'Phone: ${employee['phone']}\nEducation: ${employee['education']}'),
Text('Status: ${employee['status']}'),
],
), // Display employee name
onTap: () {
// Add any action you want when the employee is tapped
},
leading: IconButton(
onPressed: () {
makePhoneCall(employee['phone'].toString());
// launchCommunication(
// 'phone', employee['phone'].toString(), '');
},
icon: const Icon(Icons.phone),
),
),
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
employeeController.id = employeeController.generateRandomId(8);
Get.to(
employeeFields(employeeController),
);
}, // Icon to display
backgroundColor: Colors.blue, // Button color (optional)
tooltip: 'Add Employee',
child: const Icon(Icons.add), // Tooltip text when long-pressed
),
);
});
}
Scaffold employeeFields(EmployeeController employeeController) {
return Scaffold(
appBar: AppBar(),
body: Form(
key: employeeController.formKey,
child: SizedBox(
height: 500,
child: ListView(
children: [
MyElevatedButton(
title: 'front id',
onPressed: () async {
await ImageController().choosImage(AppLink.uploadEgypt,
'idFrontEmployee', employeeController.id);
}),
MyElevatedButton(
title: 'back id',
onPressed: () async {
await ImageController().choosImage(AppLink.uploadEgypt,
'idbackEmployee', employeeController.id);
}),
MyTextForm(
controller: employeeController.name,
label: 'name',
hint: 'name',
type: TextInputType.name),
MyTextForm(
controller: employeeController.education,
label: 'education',
hint: 'education',
type: TextInputType.name),
MyTextForm(
controller: employeeController.site,
label: 'site',
hint: 'site',
type: TextInputType.name),
MyTextForm(
controller: employeeController.phone,
label: 'phone',
hint: 'phone',
type: TextInputType.phone),
MyTextForm(
controller: employeeController.status,
label: 'status',
hint: 'status',
type: TextInputType.name),
],
),
),
),
bottomNavigationBar: MyElevatedButton(
title: 'upload',
onPressed: () async {
if (employeeController.formKey.currentState!.validate()) {
await employeeController.addEmployee();
}
},
),
);
}
}
class EmployeeDetails extends StatelessWidget {
const EmployeeDetails({super.key, required this.index});
final int index;
@override
Widget build(BuildContext context) {
return MyScafolld(
title: 'Details',
isleading: true,
body: [
GetBuilder<EmployeeController>(builder: (employeeController) {
return Column(
children: [
SizedBox(
height: 200,
width: 400,
child: Image.network(
'https://sefer.click/sefer/card_image/idFrontEmployee-${employeeController.employee[index]['id']}.jpg'),
),
const SizedBox(
height: 10,
),
SizedBox(
height: 200,
width: 400,
child: Image.network(
'https://sefer.click/sefer/card_image/idFrontEmployee-${employeeController.employee[index]['id']}.jpg'),
)
],
);
})
],
);
}
}

View File

@@ -0,0 +1,107 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:sefer_admin1/constant/links.dart';
import 'package:sefer_admin1/controller/functions/crud.dart';
import 'package:sefer_admin1/views/widgets/my_textField.dart';
import '../../print.dart';
class PackageUpdateScreen extends StatelessWidget {
final PackageController packageController = Get.put(PackageController());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Package Update'),
),
body: GetBuilder<PackageController>(builder: (packageController) {
return Center(
child: ListView.builder(
itemCount: packageController.packages.length,
itemBuilder: (context, index) {
var package = packageController.packages[index];
return ListTile(
title: Text(package['appName']),
subtitle: Text(
'Platform: ${package['platform']} \nVersion: ${package['version']}'),
trailing: const Icon(Icons.update),
onTap: () {
Get.defaultDialog(
title: 'Update',
middleText: '',
content: Column(
children: [
Text(package['appName']),
Text(package['platform']),
Text(package['version']),
MyTextForm(
controller: packageController.versionController,
label: package['version'].toString(),
hint: package['version'].toString(),
type: const TextInputType.numberWithOptions(
decimal: true),
),
],
),
onConfirm: () async {
await packageController.updatePackages(
package['id'].toString(),
packageController.versionController.text.toString(),
);
},
onCancel: () {},
);
},
);
},
),
);
}),
);
}
}
class PackageController extends GetxController {
List packages = []; // Observable list to hold package info
var isLoading = false.obs;
final versionController = TextEditingController();
final formKey = GlobalKey<FormState>();
@override
void onInit() {
super.onInit();
fetchPackages();
}
// Method to fetch package data from API
fetchPackages() async {
var response = await CRUD().get(link: AppLink.getPackages, payload: {});
if (response != 'failure') {
var jsonData = jsonDecode(response);
packages = jsonData['message'];
update();
Log.print('jsonData: ${jsonData}');
}
}
updatePackages(String id, version) async {
var response = await CRUD().post(
link: AppLink.updatePackages,
payload: {
"id": id,
"version": version,
},
);
Log.print('response: ${response}');
if (response != 'failure') {
Get.back();
fetchPackages();
} else {
Get.snackbar('error', 'message');
}
}
}

View File

@@ -354,6 +354,18 @@ class StaticDash extends StatelessWidget {
show: true, show: true,
color: Colors.green.withOpacity(0.3)), color: Colors.green.withOpacity(0.3)),
), ),
LineChartBarData(
spots: staticController
.chartDataEmployeeSefer4,
isCurved: true,
color:
Colors.yellow, // Custom color for Mena
barWidth: 3,
dotData: const FlDotData(show: true),
belowBarData: BarAreaData(
show: true,
color: Colors.yellow.withOpacity(0.3)),
),
], ],
titlesData: const FlTitlesData( titlesData: const FlTitlesData(
bottomTitles: AxisTitles( bottomTitles: AxisTitles(

View File

@@ -51,7 +51,7 @@ class MyTextForm extends StatelessWidget {
return 'Please enter a valid email.'.tr; return 'Please enter a valid email.'.tr;
} }
} else if (type == TextInputType.phone) { } else if (type == TextInputType.phone) {
if (value.length != 10) { if (value.length != 11) {
return 'Please enter a valid phone number.'.tr; return 'Please enter a valid phone number.'.tr;
} }
} }

View File

@@ -9,6 +9,7 @@ import file_selector_macos
import firebase_core import firebase_core
import firebase_crashlytics import firebase_crashlytics
import firebase_messaging import firebase_messaging
import flutter_image_compress_macos
import flutter_secure_storage_macos import flutter_secure_storage_macos
import google_sign_in_ios import google_sign_in_ios
import path_provider_foundation import path_provider_foundation
@@ -20,6 +21,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin")) FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin"))
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
FlutterImageCompressMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterImageCompressMacosPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))

View File

@@ -374,6 +374,54 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_image_compress:
dependency: "direct main"
description:
name: flutter_image_compress
sha256: "45a3071868092a61b11044c70422b04d39d4d9f2ef536f3c5b11fb65a1e7dd90"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
flutter_image_compress_common:
dependency: transitive
description:
name: flutter_image_compress_common
sha256: "7f79bc6c8a363063620b4e372fa86bc691e1cb28e58048cd38e030692fbd99ee"
url: "https://pub.dev"
source: hosted
version: "1.0.5"
flutter_image_compress_macos:
dependency: transitive
description:
name: flutter_image_compress_macos
sha256: "26df6385512e92b3789dc76b613b54b55c457a7f1532e59078b04bf189782d47"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
flutter_image_compress_ohos:
dependency: transitive
description:
name: flutter_image_compress_ohos
sha256: e76b92bbc830ee08f5b05962fc78a532011fcd2041f620b5400a593e96da3f51
url: "https://pub.dev"
source: hosted
version: "0.0.3"
flutter_image_compress_platform_interface:
dependency: transitive
description:
name: flutter_image_compress_platform_interface
sha256: "579cb3947fd4309103afe6442a01ca01e1e6f93dc53bb4cbd090e8ce34a41889"
url: "https://pub.dev"
source: hosted
version: "1.0.5"
flutter_image_compress_web:
dependency: transitive
description:
name: flutter_image_compress_web
sha256: f02fe352b17f82b72f481de45add240db062a2585850bea1667e82cc4cd6c311
url: "https://pub.dev"
source: hosted
version: "0.1.4+1"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -62,6 +62,7 @@ dependencies:
# webview_flutter: ^4.7.0 # webview_flutter: ^4.7.0
googleapis_auth: ^1.6.0 googleapis_auth: ^1.6.0
firebase_crashlytics: ^3.5.7 firebase_crashlytics: ^3.5.7
flutter_image_compress: ^2.3.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: