From 5fc160e3742edd62f7e81ced46bd5f326a58728a Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Fri, 1 May 2026 01:43:59 +0300 Subject: [PATCH] 19 --- lib/constant/colors.dart | 52 +- lib/constant/credential.dart | 2 +- lib/constant/links.dart | 14 +- lib/constant/style.dart | 126 +- .../admin/dashboard_controller.dart | 20 +- lib/controller/admin/staff_controller.dart | 81 + lib/controller/auth/otp_helper.dart | 190 +- .../employee_controller.dart | 14 +- lib/controller/functions/crud.dart | 1696 ++--------------- lib/controller/functions/device_info.dart | 23 +- lib/debug_jwt.dart | 22 + lib/main.dart | 8 +- lib/views/admin/admin_home_page.dart | 51 +- .../admin/drivers/driver_gift_check_page.dart | 19 +- .../admin/drivers/driver_tracker_screen.dart | 19 +- .../admin/enceypt/fingerprint_migration.dart | 15 +- lib/views/admin/packages.dart | 16 +- lib/views/admin/staff/add_staff_page.dart | 195 ++ .../admin/staff/pending_admins_page.dart | 148 ++ lib/views/auth/login_page.dart | 84 +- lib/views/auth/register_page.dart | 181 ++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 - macos/Podfile.lock | 15 +- pubspec.lock | 388 ++-- windows/flutter/generated_plugins.cmake | 1 + 25 files changed, 1526 insertions(+), 1856 deletions(-) create mode 100644 lib/controller/admin/staff_controller.dart create mode 100644 lib/debug_jwt.dart create mode 100644 lib/views/admin/staff/add_staff_page.dart create mode 100644 lib/views/admin/staff/pending_admins_page.dart create mode 100644 lib/views/auth/register_page.dart diff --git a/lib/constant/colors.dart b/lib/constant/colors.dart index 18c087a..efde492 100644 --- a/lib/constant/colors.dart +++ b/lib/constant/colors.dart @@ -1,14 +1,46 @@ import 'package:flutter/material.dart'; +import 'package:flutter/material.dart'; + class AppColor { - static const Color primaryColor = Colors.black; - static const Color secondaryColor = Colors.white; - static const Color accentColor = Colors.grey; - static const Color redColor = Color(0xFFEA4335); // Google Red - static const Color greenColor = Color(0xFF34A853); // Google Green - static const Color blueColor = - Color.fromARGB(255, 66, 135, 246); // Google Blue - static const Color yellowColor = Color(0xFFFBBC05); // Google Yellow - static Color deepPurpleAccent = - const Color.fromARGB(255, 123, 76, 254).withOpacity(0.3); + // --- Core Design Tokens --- + + // Background & Surfaces + static const Color bg = Color(0xFF0A0A0B); + static const Color surface = Color(0xFF161618); + static const Color surfaceElevated = Color(0xFF222225); + static const Color surfaceGlass = Color(0xCC161618); + + // Accents & Branding + static const Color accent = Color(0xFF6366F1); // Indigo / Violet + static const Color accentSoft = Color(0x266366F1); // 15% Opacity + static const Color accentBorder = Color(0x4D6366F1); // 30% Opacity + static const Color glow = Color(0xFF818CF8); + + // Semantic / State Colors + static const Color danger = Color(0xFFEF4444); + static const Color dangerSoft = Color(0x26EF4444); + static const Color success = Color(0xFF10B981); + static const Color successSoft = Color(0x2610B981); + static const Color warning = Color(0xFFF59E0B); + static const Color info = Color(0xFF3B82F6); + + // Text & Content + static const Color textPrimary = Color(0xFFF3F4F6); + static const Color textSecondary = Color(0xFF9CA3AF); + static const Color textMuted = Color(0xFF6B7280); + + // UI Elements + static const Color divider = Color(0xFF2D2D30); + static const Color cardShadow = Color(0x66000000); + + // --- Legacy Mappings (for temporary compatibility) --- + static const Color primaryColor = bg; + static const Color secondaryColor = textPrimary; + static const Color accentColor = accent; + static const Color redColor = danger; + static const Color greenColor = success; + static const Color blueColor = info; + static const Color yellowColor = warning; } + diff --git a/lib/constant/credential.dart b/lib/constant/credential.dart index 0054b50..d79d566 100644 --- a/lib/constant/credential.dart +++ b/lib/constant/credential.dart @@ -11,7 +11,7 @@ class AC { gAK() async { if (box.read(BoxName.apiKeyRun).toString() != 'run') { var res = await CRUD().get(link: AppLink.getApiKey, payload: {}); - var decod = jsonDecode(res); + var decod = res is String ? jsonDecode(res) : res; print(decod); Map jsonData = {}; for (var i = 0; i < decod['message'].length; i++) { diff --git a/lib/constant/links.dart b/lib/constant/links.dart index 28e5799..ba7469f 100644 --- a/lib/constant/links.dart +++ b/lib/constant/links.dart @@ -11,7 +11,15 @@ class AppLink { // static final String endPoint = box.read(BoxName.serverChosen); // static final String server = Env.seferCairoServer; - static final String server = 'https://api.intaleq.xyz/intaleq_v1'; + static final String server = 'https://api.intaleq.xyz/intaleq_v3'; + static final String endPoint = 'https://api.intaleq.xyz/intaleq_v3'; + static final String syria = 'https://syria.intaleq.xyz/intaleq'; + static String paymentServer = 'https://walletintaleq.intaleq.xyz/v1/main'; + static String locationServer = 'https://location.intaleq.xyz/intaleq/ride/location'; + static String locationServerSide = 'https://location.intaleq.xyz/intaleq/ride/location'; + static String mapSaasRoute = 'https://map-saas.intaleqapp.com/api/maps/route'; + static String mapSaasPlaces = 'https://map-saas.intaleqapp.com/api/geocoding/places'; + static const String routeApiBaseUrl = "https://routesjo.intaleq.xyz/route/v1/driving"; static String loginJwtDriver = "https://api.intaleq.xyz/intaleq/loginAdmin.php"; //============================= @@ -35,6 +43,7 @@ class AppLink { static String test = "$server/test.php"; static String loginWalletAdmin = "$seferPaymentServer/loginWalletAdmin.php"; + static String loginWalletAdminV3 = "$server/Admin/auth/loginWallet.php"; //===============firebase========================== static String getTokens = "$server/ride/firebase/get.php"; static String getInvoices = "$server/Admin/adminUser/invoice_total.php"; @@ -209,7 +218,7 @@ class AppLink { static String uploadEgypt = "$server/uploadEgypt.php"; //==================certifcate========== - static String location = '$server/ride/location'; + static String location = locationServer; static String getCarsLocationByPassenger = "$location/get.php"; static String getFemalDriverLocationByPassenger = "$location/getFemalDriver.php"; @@ -277,6 +286,7 @@ class AppLink { "$server/auth/syria/driver/driver_details.php"; static String deleteCaptain = "$server/Admin/driver/deleteCaptain.php"; static String addAdminUser = "$server/Admin/adminUser/add.php"; + static String addStaff = "$server/Admin/Staff/add.php"; static String getdashbord = "$server/Admin/dashbord.php"; static String getEmployee = "$server/Admin/employee/get.php"; static String getBestDriver = "$server/Admin/driver/getBestDriver.php"; diff --git a/lib/constant/style.dart b/lib/constant/style.dart index 71eab1c..02bdefd 100644 --- a/lib/constant/style.dart +++ b/lib/constant/style.dart @@ -6,59 +6,81 @@ import 'box_name.dart'; import 'colors.dart'; class AppStyle { - static TextStyle headTitle = const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 40, - color: AppColor.accentColor, - ); - static TextStyle headTitle2 = const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 26, - color: AppColor.primaryColor, - ); - static TextStyle title = const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - color: AppColor.primaryColor, - ); - static TextStyle subtitle = const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 13, - color: AppColor.primaryColor, - ); - static TextStyle number = const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: AppColor.primaryColor, + // --- Typography --- + + static TextStyle display = GoogleFonts.inter( + fontWeight: FontWeight.w800, + fontSize: 32, + color: AppColor.textPrimary, + letterSpacing: -1, ); - static BoxDecoration boxDecoration = const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(12)), - color: AppColor.secondaryColor, - boxShadow: [ - BoxShadow( - color: AppColor.accentColor, - offset: Offset(-3, -3), - blurRadius: 0, - spreadRadius: 0, - blurStyle: BlurStyle.outer), - BoxShadow( - color: AppColor.accentColor, - offset: Offset(3, 3), - blurRadius: 0, - spreadRadius: 0, - blurStyle: BlurStyle.outer) - ]); - static BoxDecoration boxDecoration1 = const BoxDecoration( - boxShadow: [ - BoxShadow( - color: AppColor.accentColor, blurRadius: 5, offset: Offset(2, 4)), - BoxShadow( - color: AppColor.accentColor, blurRadius: 5, offset: Offset(-2, -2)) - ], - color: AppColor.secondaryColor, - borderRadius: BorderRadius.all( - Radius.elliptical(15, 30), - ), + static TextStyle headTitle = GoogleFonts.cairo( + fontWeight: FontWeight.bold, + fontSize: 24, + color: AppColor.textPrimary, ); + + static TextStyle title = GoogleFonts.inter( + fontWeight: FontWeight.w600, + fontSize: 16, + color: AppColor.textPrimary, + ); + + static TextStyle subtitle = GoogleFonts.inter( + fontWeight: FontWeight.w500, + fontSize: 14, + color: AppColor.textSecondary, + ); + + static TextStyle body = GoogleFonts.inter( + fontWeight: FontWeight.normal, + fontSize: 14, + color: AppColor.textPrimary, + ); + + static TextStyle caption = GoogleFonts.inter( + fontWeight: FontWeight.w400, + fontSize: 12, + color: AppColor.textMuted, + ); + + static TextStyle number = GoogleFonts.jetBrainsMono( + fontWeight: FontWeight.bold, + fontSize: 15, + color: AppColor.accent, + ); + + // --- Decorations --- + + static BoxDecoration cardDecoration = BoxDecoration( + color: AppColor.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: AppColor.divider, width: 1), + boxShadow: const [ + BoxShadow( + color: AppColor.cardShadow, + blurRadius: 20, + offset: Offset(0, 8), + ), + ], + ); + + static BoxDecoration elevatedCard = BoxDecoration( + color: AppColor.surfaceElevated, + borderRadius: BorderRadius.circular(20), + border: Border.all(color: AppColor.accentBorder, width: 1), + ); + + static BoxDecoration glassDecoration = BoxDecoration( + color: AppColor.surfaceGlass, + borderRadius: BorderRadius.circular(24), + border: Border.all(color: AppColor.divider, width: 1), + ); + + // --- Legacy Mappings --- + static TextStyle headTitle2 = headTitle; + static BoxDecoration boxDecoration = cardDecoration; + static BoxDecoration boxDecoration1 = elevatedCard; } + diff --git a/lib/controller/admin/dashboard_controller.dart b/lib/controller/admin/dashboard_controller.dart index d41d13f..c18375d 100644 --- a/lib/controller/admin/dashboard_controller.dart +++ b/lib/controller/admin/dashboard_controller.dart @@ -25,10 +25,16 @@ class DashboardController extends GetxController { var res = await CRUD().get(link: AppLink.getdashbord, payload: {}); print('📡 Main dashboard response: $res'); - if (res != 'failure') { - var d = jsonDecode(res); - print('✅ Decoded main dashboard: ${jsonEncode(d)}'); - dashbord = d['message']; + if (res != 'failure' && res != null) { + try { + var d = res is String ? jsonDecode(res) : res; + print('✅ Decoded main dashboard: ${jsonEncode(d)}'); + if (d['status'] == 'success' && d['message'] != null) { + dashbord = d['message'] is List ? d['message'] : [d['message']]; + } + } catch (e) { + print('❌ Error parsing main dashboard: $e'); + } } else { print('❌ Failed to load main dashboard'); } @@ -40,7 +46,7 @@ class DashboardController extends GetxController { ); print('💳 Wallet dashboard response: $resPayments'); - if (resPayments != 'failure') { + if (resPayments is Map && resPayments['status'] == 'success') { var p = resPayments; print('✅ Decoded wallet dashboard: ${jsonEncode(p)}'); @@ -48,9 +54,11 @@ class DashboardController extends GetxController { p['message'] is List && p['message'].isNotEmpty) { dashbord[0].addAll(p['message'][0]); + } else if (dashbord.isNotEmpty && p['message'] is Map) { + dashbord[0].addAll(p['message']); } } else { - print('❌ Failed to load wallet dashboard'); + print('❌ Failed to load wallet dashboard (or verification required)'); } // 🔹 Check SMS credit diff --git a/lib/controller/admin/staff_controller.dart b/lib/controller/admin/staff_controller.dart new file mode 100644 index 0000000..ad09666 --- /dev/null +++ b/lib/controller/admin/staff_controller.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../constant/links.dart'; +import '../functions/crud.dart'; +import '../functions/device_info.dart'; +import '../../views/widgets/snackbar.dart'; + +class StaffController extends GetxController { + final CRUD _crud = CRUD(); + final formKey = GlobalKey(); + + // التكست كنترولرز + final nameController = TextEditingController(); + final phoneController = TextEditingController(); + final emailController = TextEditingController(); + final passwordController = TextEditingController(); + final birthdateController = TextEditingController(); + + String selectedGender = 'Male'; + String selectedRole = 'service'; // 'admin' or 'service' + + bool isLoading = false; + + Future registerStaff() async { + if (!formKey.currentState!.validate()) return; + + isLoading = true; + update(); + + try { + // ملاحظة: لا نأخذ بصمة جهاز الأدمن هنا، بل نتركها فارغة ليقوم الموظف بربطها عند أول دخول له + String fingerprint = ""; + + var response = await _crud.post( + link: AppLink.addStaff, + payload: { + "name": nameController.text.trim(), + "phone": phoneController.text.trim(), + "email": emailController.text.trim(), + "password": passwordController.text.trim(), + "role": selectedRole, + "gender": selectedGender, + "birthdate": birthdateController.text.trim(), + "fingerprint": fingerprint, + "site": "main", // القيمة الافتراضية للفرع + }, + ); + + if (response != "failure") { + mySnackbarSuccess('تمت إضافة الموظف بنجاح'); + _clearFields(); + Get.back(); + } else { + mySnackeBarError('فشل في إضافة الموظف. يرجى المحاولة لاحقاً'); + } + } catch (e) { + mySnackeBarError('حدث خطأ: $e'); + } finally { + isLoading = false; + update(); + } + } + + void _clearFields() { + nameController.clear(); + phoneController.clear(); + emailController.clear(); + passwordController.clear(); + birthdateController.clear(); + } + + @override + void onClose() { + nameController.dispose(); + phoneController.dispose(); + emailController.dispose(); + passwordController.dispose(); + birthdateController.dispose(); + super.onClose(); + } +} diff --git a/lib/controller/auth/otp_helper.dart b/lib/controller/auth/otp_helper.dart index 25abbba..f81478d 100644 --- a/lib/controller/auth/otp_helper.dart +++ b/lib/controller/auth/otp_helper.dart @@ -1,14 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:jwt_decoder/jwt_decoder.dart'; import 'package:get/get.dart'; import 'package:sefer_admin1/controller/functions/device_info.dart'; import 'package:sefer_admin1/views/auth/login_page.dart'; import '../../constant/box_name.dart'; import '../../constant/links.dart'; +import '../../constant/info.dart'; import '../../main.dart'; import '../../print.dart'; import '../../views/admin/admin_home_page.dart'; import '../../views/widgets/snackbar.dart'; import '../functions/crud.dart'; +import '../functions/encrypt_decrypt.dart'; class OtpHelper extends GetxController { static final String _sendOtpUrl = @@ -73,27 +77,181 @@ class OtpHelper extends GetxController { } } - Future checkAdminLogin() async { - final deviceNumber = - box.read(BoxName.fingerPrint); // خزّنه عند التشغيل أول مرة - final phoneNumber = box.read(BoxName.adminPhone); // عند التحقق من OTP - - if (deviceNumber != null && phoneNumber != null) { + /// تسجيل الدخول بكلمة المرور والبصمة + Future loginWithPassword(String password) async { + try { + final fingerprint = box.read(BoxName.fingerPrint); final response = await CRUD().post( link: _checkAdminLogin, payload: { - "device_number": deviceNumber, - "phone_number": phoneNumber, + 'fingerprint': fingerprint, + 'password': password, }, ); - if (response != "failure") { - Get.offAll(() => AdminHomePage()); + if (response != 'failure') { + // إذا كان الرد يتطلب OTP (السيرفر يرجعها بداخل message) + final msg = response['message']; + if (response['status'] == 'otp_required' || (msg is Map && msg['status'] == 'otp_required')) { + String phone = (msg is Map ? msg['phone'] : response['phone']) ?? ''; + _showOtpDialog(phone, password, fingerprint); + return false; // ننتظر إكمال الـ OTP + } + + // إذا نجح الدخول مباشرة + return _handleLoginSuccess(response, password); } else { - Get.offAll(() => AdminLoginPage()); + // سيقوم CRUD بإظهار الخطأ المناسب (مثل "حسابك قيد المراجعة") + return false; } + } catch (e) { + Log.print('LOGIN ERROR: $e'); + mySnackeBarError('حدث خطأ أثناء تسجيل الدخول: $e'); + return false; + } + } + + /// التحقق من OTP الخاص بتسجيل الدخول + Future verifyLoginOtp( + String phone, String otp, String password, String fingerprint) async { + try { + final response = await CRUD().post( + link: '${AppLink.server}/Admin/auth/verify_login.php', + payload: { + 'phone': phone, + 'otp': otp, + 'fingerprint': fingerprint, + }, + ); + + if (response != 'failure') { + bool success = await _handleLoginSuccess(response, password); + if (success) { + Get.offAll(() => const AdminHomePage()); + } + } + } catch (e) { + Log.print('OTP VERIFY LOGIN ERROR: $e'); + mySnackeBarError('خطأ في التحقق من الرمز: $e'); + } + } + + Future _handleLoginSuccess(dynamic response, String password) async { + final msg = response['message']; + final data = response['admin'] ?? (msg is Map ? msg['admin'] : null); + final jwt = response['jwt'] ?? (msg is Map ? msg['jwt'] : null); + + if (jwt != null) { + await box.write(BoxName.jwt, c(jwt)); + } + + if (data != null) { + if (data['id'] != null) await box.write(BoxName.driverID, data['id']); + if (data['role'] != null) { + String role = data['role'].toString().trim(); + await box.write('admin_role', role); + Log.print('Admin role saved: $role'); + } + if (data['phone'] != null) await box.write(BoxName.adminPhone, data['phone']); + } + + await box.write(BoxName.phoneVerified, true); + await box.write('admin_password', password); + + mySnackbarSuccess('تم تسجيل الدخول بنجاح'); + return true; + } + + void _showOtpDialog(String phone, String password, String fingerprint) { + String otpCode = ''; + Get.defaultDialog( + title: 'رمز التحقق', + content: Column( + children: [ + Text('تم إرسال رمز التحقق إلى WhatsApp الخاص بك ($phone)'), + const SizedBox(height: 16), + TextField( + onChanged: (val) => otpCode = val, + keyboardType: TextInputType.number, + decoration: const InputDecoration( + hintText: 'أدخل الرمز هنا', + border: OutlineInputBorder(), + ), + ), + ], + ), + textConfirm: 'تحقق', + confirmTextColor: Colors.white, + onConfirm: () { + if (otpCode.length >= 5) { + Get.back(); + verifyLoginOtp(phone, otpCode, password, fingerprint); + } else { + mySnackeBarError('الرجاء إدخال رمز صحيح'); + } + }, + ); + } + + static bool _isAutoLoginAttempted = false; + + Future checkAdminLogin() async { + final fingerprint = box.read(BoxName.fingerPrint); + final password = box.read('admin_password'); + + if (fingerprint == null || password == null) { + Get.offAll(() => const AdminLoginPage()); + return; + } + + // ─── أولاً: التحقق من وجود توكن JWT صالح ───────── + // إذا وُجد توكن غير منتهي الصلاحية → ندخل مباشرة بدون استدعاء login.php + final rawJwt = box.read(BoxName.jwt); + if (rawJwt != null) { + try { + String token = r(rawJwt.toString()).split(AppInformation.addd)[0]; + if (!JwtDecoder.isExpired(token)) { + Log.print('Valid JWT found, skipping login.php (no OTP needed)'); + Get.offAll(() => const AdminHomePage()); + return; + } + Log.print('JWT expired, need fresh login'); + } catch (e) { + Log.print('JWT decode failed: \$e, need fresh login'); + } + } + + // ─── ثانياً: لا يوجد توكن صالح → استدعاء login.php ─── + final response = await CRUD().post( + link: _checkAdminLogin, + payload: { + 'fingerprint': fingerprint, + 'password': password, + 'is_renewal': '1', + }, + ); + + if (response != 'failure') { + final msg = response['message']; + + if (response['status'] == 'otp_required' || (msg is Map && msg['status'] == 'otp_required')) { + String phone = (msg is Map ? msg['phone'] : response['phone']) ?? ''; + _showOtpDialog(phone, password, fingerprint); + return; // ننتظر إدخال رمز التحقق + } + + if (msg is Map && msg['jwt'] != null) { + box.write(BoxName.jwt, c(msg['jwt'])); + if (msg['admin'] != null && msg['admin']['id'] != null) { + box.write(BoxName.driverID, msg['admin']['id']); + } + } else if (response['jwt'] != null) { + box.write(BoxName.jwt, c(response['jwt'])); + } + Get.offAll(() => const AdminHomePage()); } else { - Get.offAll(() => AdminLoginPage()); + Log.print('Auto-login failed, redirecting to login page'); + Get.offAll(() => const AdminLoginPage()); } } @@ -104,7 +262,15 @@ class OtpHelper extends GetxController { box.write(BoxName.fingerPrint, deviceFingerprint); }); // تأجيل تنفيذ التنقل حتى تنتهي مرحلة البناء + // ⚠️ محاولة واحدة فقط للتسجيل التلقائي لمنع الحلقة اللانهائية Future.microtask(() { + if (_isAutoLoginAttempted) { + // نحن في حلقة — نتوقف ونذهب لصفحة الدخول مباشرة + Log.print('Auto-login already attempted, skipping to login page'); + return; + } + _isAutoLoginAttempted = true; + if (box.read(BoxName.phoneVerified) == true && box.read(BoxName.adminPhone) != null) { checkAdminLogin(); diff --git a/lib/controller/employee_controller/employee_controller.dart b/lib/controller/employee_controller/employee_controller.dart index d9c61dc..b181454 100644 --- a/lib/controller/employee_controller/employee_controller.dart +++ b/lib/controller/employee_controller/employee_controller.dart @@ -18,11 +18,17 @@ class EmployeeController extends GetxController { fetchEmployee() async { var res = await CRUD().get(link: AppLink.getEmployee, payload: {}); - if (res != 'failure') { - employee = jsonDecode(res)['message']; + if (res is String && (res == 'failure' || res == 'token_expired')) { + Get.snackbar('error', 'Failed to load employees', backgroundColor: AppColor.redColor); + return; + } + + try { + var jsonData = res is String ? jsonDecode(res) : res; + employee = jsonData['message']; update(); - } else { - Get.snackbar('error', '', backgroundColor: AppColor.redColor); + } catch (e) { + Get.snackbar('error', 'Invalid server response', backgroundColor: AppColor.redColor); } } diff --git a/lib/controller/functions/crud.dart b/lib/controller/functions/crud.dart index 1bf53a8..245591d 100644 --- a/lib/controller/functions/crud.dart +++ b/lib/controller/functions/crud.dart @@ -15,11 +15,18 @@ import '../../env/env.dart'; import '../../main.dart'; import '../../print.dart'; import 'device_info.dart'; +import 'encrypt_decrypt.dart'; import 'security_checks.dart'; class CRUD { var dev = ''; getJWT() async { + // إذا كان الأدمن مسجل دخوله بالفعل، لا تقم بتوليد توكن "ضيف" قديم + if (box.read(BoxName.driverID) != null) { + Log.print('Admin session active. Skipping guest JWT.'); + return; + } + dev = Platform.isAndroid ? 'android' : 'ios'; var payload = { @@ -47,130 +54,150 @@ class CRUD { required String link, Map? payload, }) async { - if (box.read(BoxName.jwt) == null) { + String token = ''; + var rawJwt = box.read(BoxName.jwt); + + if (rawJwt == null) { await getJWT(); + rawJwt = box.read(BoxName.jwt); } - bool isTokenExpired = JwtDecoder.isExpired(X - .r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs) - .toString() - .split(AppInformation.addd)[0]); - if (isTokenExpired) { - await getJWT(); + + if (rawJwt != null) { + token = r(rawJwt.toString()).split(AppInformation.addd)[0]; + try { + if (JwtDecoder.isExpired(token)) { + // If we have an admin ID, we should probably re-login or refresh, + // but for now let's just fall back to guest JWT if needed. + if (box.read(BoxName.driverID) == null) { + await getJWT(); + token = r(box.read(BoxName.jwt).toString()) + .split(AppInformation.addd)[0]; + } + } + } catch (e) { + print('❌ JWT Decode Error: $e'); + // If decryption failed, try using raw (maybe it was saved plain) + token = rawJwt.toString().split(AppInformation.addd)[0]; + } } - // await Get.put(LoginDriverController()).getJWT(); - var url = Uri.parse( - link, - ); + var url = Uri.parse(link); + Log.print('--- [CRUD GET] ---'); + Log.print('URL: $link'); + Log.print('Payload: $payload'); + var response = await http.post( url, body: payload, headers: { "Content-Type": "application/x-www-form-urlencoded", - 'Authorization': - 'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}' + 'Authorization': 'Bearer $token', + 'X-Device-FP': box.read(BoxName.fingerPrint) ?? '', }, ); - print(response.request); - Log.print('response.body: ${response.body}'); - print(payload); + + Log.print('Status Code: ${response.statusCode}'); + Log.print('Response Body: ${response.body}'); + Log.print('------------------'); + if (response.statusCode == 200) { - Log.print('response: ${response.body}'); - var jsonData = jsonDecode(response.body); - if (jsonData['status'] == 'success') { - return response.body; - } - - return jsonData['status']; - } else if (response.statusCode == 401) { - // Specifically handle 401 Unauthorized - var jsonData = jsonDecode(response.body); - - if (jsonData['error'] == 'Token expired') { - // Show snackbar prompting to re-login - // await Get.put(LoginDriverController()).getJWT(); - // mySnackbarSuccess('please order now'.tr); - - return 'token_expired'; // Return a specific value for token expiration - } else { - // Other 401 errors - // addError('Unauthorized: ${jsonData['error']}', 'crud().post - 401'); + try { + var jsonData = jsonDecode(response.body); + if (jsonData['status'] == 'success') { + return response.body; + } + return jsonData['status'] ?? 'failure'; + } catch (e) { return 'failure'; } + } else if (response.statusCode == 401) { + return 'token_expired'; } else { - // addError('Non-200 response code: ${response.statusCode}', - // 'crud().post - Other'); return 'failure'; } } - // Future getWallet({ - // required String link, - // Map? payload, - // }) async { - // var s = await getJwtWallet(); - // var url = Uri.parse( - // link, - // ); - // var response = await http.post( - // url, - // body: payload, - // headers: { - // "Content-Type": "application/x-www-form-urlencoded", - // 'Authorization': 'Bearer $s' - // }, - // ); - // if (response.statusCode == 200) { - // var jsonData = jsonDecode(response.body); - // if (jsonData['status'] == 'success') { - // return response.body; - // } + Future getWallet({ + required String link, + Map? payload, + }) async { + var s = await getJwtWallet(); + final hmac = box.read(BoxName.hmac); + var url = Uri.parse(link); - // return jsonData['status']; - // } else if (response.statusCode == 401) { - // // Specifically handle 401 Unauthorized - // var jsonData = jsonDecode(response.body); + // إضافة الـ HMAC للـ payload لزيادة التوافقية + if (payload != null && hmac != null) { + payload['hmac'] = hmac.toString(); + } - // if (jsonData['error'] == 'Token expired') { - // // Show snackbar prompting to re-login - // // await Get.put(LoginDriverController()).getJwtWallet(); + var response = await http.post( + url, + body: payload, + headers: { + "Content-Type": "application/x-www-form-urlencoded", + 'Authorization': 'Bearer $s', + 'X-HMAC-Auth': hmac.toString(), + 'X-Device-FP': box.read(BoxName.fingerPrint) ?? '', + }, + ); - // return 'token_expired'; // Return a specific value for token expiration - // } else { - // // Other 401 errors - // addError('Unauthorized: ${jsonData['error']}', 'crud().post - 401'); - // return 'failure'; - // } - // } else { - // addError('Non-200 response code: ${response.statusCode}', - // 'crud().post - Other'); - // return 'failure'; - // } - // } + if (response.statusCode == 200) { + try { + var jsonData = jsonDecode(response.body); + if (jsonData['status'] == 'success') { + return jsonData; + } + return jsonData['status'] ?? 'failure'; + } catch (e) { + return 'failure'; + } + } else if (response.statusCode == 401) { + await getJwtWallet(); + return 'token_expired'; + } else { + return 'failure'; + } + } Future post( {required String link, Map? payload}) async { var url = Uri.parse(link); try { - bool isTokenExpired = JwtDecoder.isExpired(X - .r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs) - .toString() - .split(AppInformation.addd)[0]); - if (isTokenExpired) { - await getJWT(); + String token = ''; + var rawJwt = box.read(BoxName.jwt); + + if (rawJwt != null) { + token = r(rawJwt.toString()).split(AppInformation.addd)[0]; + try { + if (JwtDecoder.isExpired(token)) { + if (box.read(BoxName.driverID) == null) { + await getJWT(); + token = r(box.read(BoxName.jwt).toString()) + .split(AppInformation.addd)[0]; + } + } + } catch (e) { + token = rawJwt.toString().split(AppInformation.addd)[0]; + } } + + Log.print('--- [CRUD POST] ---'); + Log.print('URL: $link'); + Log.print('Payload: $payload'); + var response = await http.post( url, body: payload, headers: { "Content-Type": "application/x-www-form-urlencoded", - 'Authorization': - 'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}' - // 'Authorization': 'Bearer ${box.read(BoxName.jwt)}' + 'Authorization': 'Bearer $token', + 'X-Device-FP': box.read(BoxName.fingerPrint) ?? '', }, ); - print(response.request); - Log.print('response.body: ${response.body}'); - print(payload); + + Log.print('Status Code: ${response.statusCode}'); + Log.print('Response Body: ${response.body}'); + Log.print('-------------------'); + if (response.statusCode == 200) { try { var jsonData = jsonDecode(response.body); @@ -180,35 +207,11 @@ class CRUD { return jsonData['status']; } } catch (e) { - // addError(e.toString(), 'crud().post - JSON decoding'); return 'failure'; } } else if (response.statusCode == 401) { - // Specifically handle 401 Unauthorized - var jsonData = jsonDecode(response.body); - - if (jsonData['error'] == 'Token expired') { - // Show snackbar prompting to re-login - await getJWT(); - // MyDialog().getDialog( - // 'Session expired. Please log in again.'.tr, - // '', - // () { - // Get.put(LoginController()).loginUsingCredentials( - // box.read(BoxName.passengerID), box.read(BoxName.email)); - // Get.back(); - // }, - // ); - - return 'token_expired'; // Return a specific value for token expiration - } else { - // Other 401 errors - // addError('Unauthorized: ${jsonData['error']}', 'crud().post - 401'); - return 'failure'; - } + return 'token_expired'; } else { - // addError('Non-200 response code: ${response.statusCode}', - // 'crud().post - Other'); return 'failure'; } } catch (e) { @@ -218,30 +221,90 @@ class CRUD { } getJwtWallet() async { + // 1. فحص التوكن المخزن أولاً (Caching) لتقليل طلبات الـ SSO + var cachedWalletJwt = box.read('wallet_jwt'); + var cachedWalletExpiry = box.read('wallet_jwt_expiry'); + + if (cachedWalletJwt != null && cachedWalletExpiry != null) { + int expiryMs = int.tryParse(cachedWalletExpiry.toString()) ?? 0; + // إذا لم ينته بعد (مع هامش أمان 60 ثانية) + if (DateTime.now().millisecondsSinceEpoch < expiryMs - 60000) { + Log.print( + 'Using cached Wallet JWT. Expiry: ${DateTime.fromMillisecondsSinceEpoch(expiryMs)}'); + return cachedWalletJwt.toString(); + } + } + String fingerPrint = await DeviceHelper.getDeviceFingerprint(); - print('fingerPrint: ${fingerPrint}'); + final mainTokenEnc = box.read(BoxName.jwt); + if (mainTokenEnc == null) return null; - //await SecurityChecks.isDeviceRootedFromNative(Get.context!); + String mainToken = mainTokenEnc.toString(); + // فك تشفير التوكن بنفس طريقة دالة get() التي تعمل بنجاح + try { + mainToken = r(mainTokenEnc.toString()).split(AppInformation.addd)[0]; + } catch (e) { + // إذا فشل فك التشفير، نستخدم القيمة كما هي (ربما مخزنة بدون تشفير) + mainToken = mainTokenEnc.toString().split(AppInformation.addd)[0]; + } + Log.print('Wallet SSO mainToken length: ${mainToken.length}'); + Log.print('Wallet SSO token starts with: ${mainToken.substring(0, mainToken.length > 10 ? 10 : mainToken.length)}'); - dev = Platform.isAndroid ? 'android' : 'ios'; - var payload = { - 'id': '1', - 'password': AK.passnpassenger, - 'aud': '${Env.allowedWallet}$dev', - 'fingerPrint': fingerPrint - }; - // Log.print('payload: ${payload}'); + // استخدام الـ SSO للسيرفر الرئيسي إذا كان الأدمن مسجل دخوله var response1 = await http.post( - Uri.parse(AppLink.loginWalletAdmin), - body: payload, + Uri.parse(AppLink.loginWalletAdminV3), + headers: { + 'Authorization': 'Bearer $mainToken', + 'X-Device-FP': fingerPrint, + }, ); - Log.print('response.request: ${response1.request}'); - Log.print('response.body: ${response1.body}'); - print(payload); - Log.print( - 'jsonDecode(response1.body)["jwt"]: ${jsonDecode(response1.body)['jwt']}'); - await box.write(BoxName.hmac, jsonDecode(response1.body)['hmac']); - return jsonDecode(response1.body)['jwt'].toString(); + + Log.print('Wallet SSO login status: ${response1.statusCode}'); + + if (response1.statusCode == 200) { + final decoded = jsonDecode(response1.body); + final msg = decoded['message']; + + String? jwt; + String? hmac; + + if (msg is Map) { + jwt = msg['jwt']; + hmac = msg['hmac']; + } else { + jwt = decoded['jwt']; + hmac = decoded['hmac']; + } + + if (hmac != null) await box.write(BoxName.hmac, hmac); + + // تخزين التوكن الجديد في الكاش لمدة 10 دقائق (600 ثانية) + if (jwt != null) { + await box.write('wallet_jwt', jwt); + await box.write('wallet_jwt_expiry', + (DateTime.now().millisecondsSinceEpoch + (600 * 1000)).toString()); + Log.print('Wallet JWT cached successfully.'); + } + + return jwt?.toString(); + } else { + // Fallback: المحاولة بالطريقة القديمة إذا فشل الـ SSO + var payload = { + 'id': box.read(BoxName.driverID) ?? '1', + 'password': AK.passnpassenger, + 'aud': '${Env.allowedWallet}${Platform.isAndroid ? 'android' : 'ios'}', + 'fingerPrint': fingerPrint + }; + var fallbackRes = await http.post( + Uri.parse(AppLink.loginWalletAdmin), + body: payload, + ); + if (fallbackRes.statusCode == 200) { + final decoded = jsonDecode(fallbackRes.body); + if (decoded['jwt'] != null) return decoded['jwt'].toString(); + } + } + return null; } Future postWallet( @@ -252,6 +315,12 @@ class CRUD { Log.print('hmac: ${hmac}'); var url = Uri.parse(link); Log.print('url: ${url}'); + + // إضافة الـ HMAC للـ payload لزيادة التوافقية + if (payload != null && hmac != null) { + payload['hmac'] = hmac.toString(); + } + try { // await LoginDriverController().getJWT(); @@ -262,6 +331,7 @@ class CRUD { "Content-Type": "application/x-www-form-urlencoded", 'Authorization': 'Bearer $s', 'X-HMAC-Auth': hmac.toString(), + 'X-Device-FP': box.read(BoxName.fingerPrint) ?? '', }, ); // Log.print('response.request:${response.request}'); @@ -272,27 +342,15 @@ class CRUD { var jsonData = jsonDecode(response.body); if (jsonData['status'] == 'success') { return jsonData; - } else { - return jsonData['status']; } + return jsonData['status'] ?? 'failure'; } catch (e) { - // addError(e.toString(), 'crud().post - JSON decoding'); return 'failure'; } } else if (response.statusCode == 401) { - // Specifically handle 401 Unauthorized - var jsonData = jsonDecode(response.body); - - if (jsonData['error'] == 'Token expired') { - return 'token_expired'; // Return a specific value for token expiration - } else { - // Other 401 errors - // addError('Unauthorized: ${jsonData['error']}', 'crud().post - 401'); - return 'failure'; - } + await getJwtWallet(); + return 'token_expired'; } else { - // addError('Non-200 response code: ${response.statusCode}', - // 'crud().post - Other'); return 'failure'; } } catch (e) { @@ -746,1344 +804,4 @@ class CRUD { 201023248456, 201023248456, ]; - List phoneDrivers = [ - 201000038159, - 201000038736, - 201000064464, - 201000091230, - 201000136570, - 201000151861, - 201000198736, - 201000228580, - 201000237951, - 201000255720, - 201000287614, - 201000292939, - 201000304215, - 201000332271, - 201000392607, - 201000405678, - 201000426363, - 201000435451, - 201000480175, - 201000669808, - 201000692012, - 201000892261, - 201000927483, - 201001022044, - 201001088358, - 201001195138, - 201001216083, - 201001227223, - 201001231343, - 201001281229, - 201001324045, - 201001372270, - 201001448413, - 201001456101, - 201001460169, - 201001484302, - 201001486990, - 201001609106, - 201001614305, - 201001616098, - 201001695782, - 201001741428, - 201001868999, - 201001880988, - 201001917872, - 201001974843, - 201002026121, - 201002034349, - 201002050890, - 201002205527, - 201002211383, - 201002220298, - 201002380874, - 201002507461, - 201002524889, - 201002559121, - 201002593666, - 201002726223, - 201002757121, - 201002772429, - 201002831939, - 201002918886, - 201003008890, - 201003093029, - 201003111434, - 201003247072, - 201003284035, - 201003312497, - 201003322933, - 201003335753, - 201003395388, - 201003454075, - 201003457552, - 201003464748, - 201003516746, - 201003519354, - 201003562562, - 201003624502, - 201003660350, - 201003698426, - 201003732688, - 201003758852, - 201003769330, - 201003970205, - 201003973327, - 201004008170, - 201004034125, - 201004361687, - 201004362477, - 201004378446, - 201004508215, - 201004519539, - 201004558484, - 201004625077, - 201004658742, - 201004663695, - 201004712116, - 201004754688, - 201004770495, - 201004771729, - 201004800479, - 201004848413, - 201004965744, - 201005004603, - 201005094804, - 201005126645, - 201005145830, - 201005170670, - 201005215092, - 201005259664, - 201005285496, - 201005308188, - 201005315146, - 201005457333, - 201005457388, - 201005464946, - 201005467997, - 201005496502, - 201005591720, - 201005655832, - 201005748724, - 201005778338, - 201005802822, - 201005804981, - 201005840296, - 201005857716, - 201005894006, - 201006098594, - 201006119945, - 201006261655, - 201006336012, - 201006373310, - 201006399505, - 201006529560, - 201006550621, - 201006566057, - 201006568992, - 201006576933, - 201006642448, - 201006681860, - 201006701396, - 201006775356, - 201006833930, - 201006841969, - 201006874127, - 201006886819, - 201006905156, - 201006911892, - 201006953238, - 201006997521, - 201007006197, - 201007126077, - 201007135060, - 201007174032, - 201007210871, - 201007251945, - 201007420153, - 201007431781, - 201007436392, - 201007467887, - 201007526078, - 201007532774, - 201007536613, - 201007573334, - 201007581968, - 201007737308, - 201007740820, - 201007901024, - 201007910121, - 201008018110, - 201008053391, - 201008073697, - 201008235676, - 201008269802, - 201008306697, - 201008330262, - 201008360039, - 201008527428, - 201008529970, - 201008597171, - 201008698488, - 201008864162, - 201008872941, - 201008900034, - 201008940080, - 201008968686, - 201009033817, - 201009089217, - 201009120576, - 201009150184, - 201009171151, - 201009190006, - 201009225265, - 201009440993, - 201009752899, - 201009759313, - 201009793301, - 201009797500, - 201009804581, - 201009869329, - 201009886308, - 201009939077, - 201009945537, - 201009969727, - 201010025269, - 201010041236, - 201010107223, - 201010259482, - 201010376273, - 201010382250, - 201010490869, - 201010684229, - 201010743158, - 201010789827, - 201010866363, - 201010885870, - 201010887621, - 201010887705, - 201011205708, - 201011492446, - 201011508900, - 201011604297, - 201011723604, - 201011936165, - 201011953955, - 201011999310, - 201012036826, - 201012338391, - 201012342004, - 201012475707, - 201012530826, - 201012574024, - 201012775059, - 201012856677, - 201012962316, - 201013004000, - 201013135258, - 201013248449, - 201013327761, - 201013331683, - 201013725067, - 201014063641, - 201014242962, - 201014446768, - 201014626816, - 201014687816, - 201014714084, - 201014781950, - 201014786553, - 201015084707, - 201015162969, - 201015264416, - 201015328382, - 201015493716, - 201015554008, - 201015555050, - 201015654885, - 201015665467, - 201015736460, - 201015817826, - 201015994940, - 201016388436, - 201016408801, - 201016497939, - 201016565911, - 201016636646, - 201016748176, - 201017035902, - 201017062590, - 201017212144, - 201017435616, - 201017505135, - 201017567245, - 201017580860, - 201017650550, - 201017672180, - 201017690285, - 201017815188, - 201018042320, - 201018180201, - 201018416878, - 201018518723, - 201018861694, - 201018933273, - 201018984078, - 201019023091, - 201019069097, - 201019217036, - 201019266797, - 201019502290, - 201019782128, - 201019785811, - 201019859988, - 201020007540, - 201020060588, - 201020093997, - 201020170343, - 201020172859, - 201020178391, - 201020184220, - 201020235190, - 201020301781, - 201020335329, - 201020555412, - 201020649148, - 201020695352, - 201020847945, - 201020969782, - 201021017211, - 201021160682, - 201021222549, - 201021235129, - 201021394443, - 201021655556, - 201021736217, - 201021875274, - 201022226451, - 201022246204, - 201022265083, - 201022329267, - 201022446211, - 201022518181, - 201022660026, - 201023005090, - 201023069002, - 201023069907, - 201023095063, - 201023118846, - 201023130711, - 201023247045, - 201023248455, - 201023248456, - 201023248457, - 201023248488, - 201023626140, - 201023674737, - 201023790070, - 201023848787, - 201024052053, - 201024181778, - 201024420162, - 201024470224, - 201024501874, - 201024769948, - 201025075574, - 201025227216, - 201025255404, - 201025393959, - 201025412613, - 201025432017, - 201025463793, - 201025500060, - 201025581505, - 201025647745, - 201025737661, - 201025767385, - 201025887117, - 201026191863, - 201026200067, - 201026264611, - 201026300904, - 201026440737, - 201026773473, - 201026798518, - 201026807264, - 201027030168, - 201027234885, - 201027316763, - 201027481133, - 201027605557, - 201027719574, - 201027774092, - 201027775432, - 201027788822, - 201027994009, - 201028258757, - 201028313498, - 201028340666, - 201028603589, - 201028885144, - 201028912082, - 201029116604, - 201029135123, - 201029139900, - 201029296526, - 201029362080, - 201029484514, - 201029602004, - 201029777011, - 201029885806, - 201029929017, - 201029950342, - 201030014226, - 201030039804, - 201030047331, - 201030096464, - 201030145357, - 201030282895, - 201030356606, - 201030367702, - 201030382740, - 201030499449, - 201030530211, - 201030596294, - 201030673353, - 201030751777, - 201030806901, - 201030812036, - 201030885983, - 201030985581, - 201032073723, - 201032080240, - 201032197354, - 201032215558, - 201032599049, - 201032900804, - 201032960990, - 201032995929, - 201033006950, - 201033014117, - 201033053068, - 201033054527, - 201033087547, - 201033159408, - 201033499971, - 201033552484, - 201033598513, - 201033854635, - 201033970821, - 201040535096, - 201040873577, - 201050048044, - 201050774777, - 201050797017, - 201050894194, - 201050916243, - 201050923423, - 201060037563, - 201060040065, - 201060090105, - 201060156231, - 201060163215, - 201060208601, - 201060371260, - 201060444330, - 201060525792, - 201060577208, - 201060686267, - 201060794536, - 201060896771, - 201060906267, - 201060974333, - 201061099914, - 201061131720, - 201061337043, - 201061350410, - 201061489820, - 201061973544, - 201062031886, - 201062166038, - 201062319321, - 201062415502, - 201062603244, - 201062702907, - 201062718466, - 201062981863, - 201063103737, - 201063141018, - 201063251961, - 201063308303, - 201063525249, - 201063556251, - 201063600748, - 201063688477, - 201063831389, - 201063923914, - 201063955559, - 201064026674, - 201064054511, - 201064101887, - 201064153512, - 201064178167, - 201064312767, - 201064334558, - 201064468695, - 201064626776, - 201064630354, - 201064644619, - 201064684185, - 201064921214, - 201064982002, - 201065048819, - 201065050067, - 201065161321, - 201065286286, - 201065451010, - 201065601203, - 201065635907, - 201066228870, - 201066229104, - 201066253365, - 201066292351, - 201066465787, - 201066596220, - 201066730578, - 201067611319, - 201067696612, - 201067788258, - 201067791624, - 201067859062, - 201067889013, - 201067970457, - 201067986841, - 201068212833, - 201068640092, - 201068653978, - 201069074613, - 201069133688, - 201069483289, - 201069766969, - 201069938005, - 201070021630, - 201070076171, - 201070129941, - 201070290269, - 201070641133, - 201070665752, - 201080058399, - 201080068372, - 201080076746, - 201080269149, - 201080322306, - 201080351275, - 201080454035, - 201080688081, - 201080827009, - 201080931721, - 201080979919, - 201090009131, - 201090090088, - 201090119050, - 201090213039, - 201090333810, - 201090744905, - 201090809381, - 201091029772, - 201091467068, - 201091677319, - 201091729780, - 201091951144, - 201092955061, - 201092977597, - 201093030032, - 201093092520, - 201093122561, - 201093359914, - 201093594953, - 201093882353, - 201093981308, - 201094057691, - 201094186227, - 201094255708, - 201094584806, - 201094688043, - 201094688644, - 201094769303, - 201094924486, - 201094960584, - 201095032754, - 201095288771, - 201095667357, - 201095782382, - 201095956669, - 201096133443, - 201096148124, - 201096351318, - 201096567961, - 201096662301, - 201096725050, - 201096776146, - 201097229576, - 201097267405, - 201097761778, - 201097765410, - 201097846083, - 201097919136, - 201098123666, - 201098127395, - 201098166776, - 201098386668, - 201098582216, - 201098700882, - 201098957440, - 201099336257, - 201099412985, - 201099420820, - 201099530964, - 201099550606, - 201099600846, - 201099670072, - 201099785084, - 201099907868, - 201099915861, - 201099924551, - 201099981747, - 201099997143, - 201100038956, - 201100040727, - 201100074027, - 201100082801, - 201100170600, - 201100245413, - 201100316991, - 201100485561, - 201100583911, - 201100588511, - 201100667988, - 201100680306, - 201100711857, - 201100721522, - 201100726360, - 201101163626, - 201101371471, - 201101474377, - 201101512699, - 201101626410, - 201101795866, - 201101986128, - 201102192489, - 201102432276, - 201102563435, - 201102660856, - 201102752569, - 201102766374, - 201102779987, - 201104429778, - 201110110495, - 201110121075, - 201110144858, - 201110333451, - 201110600956, - 201110668338, - 201110797333, - 201110868027, - 201110921077, - 201111047616, - 201111105976, - 201111250676, - 201111282490, - 201111300613, - 201111512106, - 201111522040, - 201111528707, - 201111667567, - 201111697961, - 201111715992, - 201111716562, - 201111718210, - 201111751166, - 201111751446, - 201111754283, - 201111951209, - 201111981450, - 201112000443, - 201112022291, - 201112044799, - 201112105588, - 201112215276, - 201112235547, - 201112299884, - 201112524534, - 201112539202, - 201112591953, - 201112861834, - 201113001950, - 201113024717, - 201113305615, - 201113328519, - 201113512958, - 201113617737, - 201113701121, - 201113931993, - 201113999375, - 201114202318, - 201114211410, - 201114384428, - 201114568129, - 201114729635, - 201114776641, - 201114801155, - 201114988892, - 201115232474, - 201115299186, - 201115307275, - 201115440591, - 201115553247, - 201115605581, - 201115691406, - 201115790410, - 201115794827, - 201115801585, - 201115892867, - 201115934957, - 201115997592, - 201116036599, - 201116062390, - 201116155328, - 201116195736, - 201116360444, - 201116362464, - 201116397705, - 201116410122, - 201116646518, - 201116661682, - 201116662263, - 201116669877, - 201116684607, - 201116787624, - 201116951169, - 201116985014, - 201117008885, - 201117059617, - 201117246068, - 201117265855, - 201117558213, - 201117651958, - 201117663059, - 201117685256, - 201117730892, - 201117745888, - 201117937985, - 201118001729, - 201118002160, - 201118175123, - 201118243930, - 201118313079, - 201118331500, - 201118342702, - 201118636820, - 201118653148, - 201118674734, - 201118689666, - 201118706518, - 201118787900, - 201118882012, - 201118886390, - 201118970961, - 201119044711, - 201119079364, - 201119100748, - 201119137787, - 201119159545, - 201119187827, - 201119256418, - 201119298768, - 201119490066, - 201119499018, - 201119557005, - 201119601947, - 201119905035, - 201119928400, - 201119993654, - 201120071355, - 201120086686, - 201120161089, - 201120194397, - 201120272743, - 201120357820, - 201120732419, - 201120760088, - 201120777527, - 201120803031, - 201120840502, - 201120917643, - 201121000454, - 201121104000, - 201121115920, - 201121218416, - 201121262634, - 201121537458, - 201121539342, - 201121641905, - 201121645943, - 201121676093, - 201121721649, - 201121738274, - 201121833893, - 201121880293, - 201121904651, - 201121999951, - 201122130454, - 201122277009, - 201122352926, - 201122352929, - 201122441260, - 201122453889, - 201122466640, - 201122681852, - 201123138354, - 201123200082, - 201123237473, - 201123338071, - 201123355123, - 201123386341, - 201123606787, - 201123850040, - 201124166622, - 201124215002, - 201124355455, - 201124484309, - 201124525303, - 201124535519, - 201124554413, - 201124585917, - 201124868717, - 201124939986, - 201125111045, - 201125308780, - 201125388876, - 201125811384, - 201125869973, - 201126002027, - 201126047174, - 201126255847, - 201126312269, - 201126442254, - 201126625122, - 201126636750, - 201126659891, - 201126669098, - 201126946975, - 201127000498, - 201127009293, - 201127010150, - 201127029020, - 201127040489, - 201127068159, - 201127100040, - 201127233460, - 201127301093, - 201127315881, - 201128008500, - 201128144862, - 201128293924, - 201128316869, - 201128399780, - 201128482002, - 201128652929, - 201128716058, - 201128852395, - 201128872000, - 201128932455, - 201129157079, - 201129158922, - 201129706750, - 201129808001, - 201140276818, - 201140490935, - 201140823736, - 201140826987, - 201141094583, - 201141191135, - 201141231122, - 201141307507, - 201141385551, - 201141438922, - 201141473992, - 201141549347, - 201141573088, - 201141614543, - 201141675135, - 201141679102, - 201141679162, - 201141696200, - 201141724381, - 201141761526, - 201141822739, - 201141941402, - 201142001090, - 201142088851, - 201142136063, - 201142224902, - 201142381399, - 201142394076, - 201142461102, - 201142492474, - 201142783738, - 201142877782, - 201142889397, - 201142985578, - 201143123876, - 201143283485, - 201143335405, - 201143490888, - 201143631229, - 201143730080, - 201143791394, - 201143915554, - 201144038991, - 201144129961, - 201144175633, - 201144224787, - 201144294246, - 201144338541, - 201144352678, - 201144601683, - 201144626239, - 201144707747, - 201145000373, - 201145579943, - 201145611618, - 201145621795, - 201145809497, - 201145814704, - 201145828830, - 201145922310, - 201146055558, - 201146207812, - 201146445021, - 201146448910, - 201146461695, - 201146628267, - 201146791090, - 201147155402, - 201147181768, - 201147333047, - 201147429209, - 201147504941, - 201147769989, - 201147912222, - 201147965344, - 201148073829, - 201148140582, - 201148163794, - 201148283337, - 201148460674, - 201148504650, - 201148581664, - 201148656049, - 201149228245, - 201149363795, - 201149492463, - 201149518708, - 201150259592, - 201150300052, - 201150304075, - 201150343503, - 201150352022, - 201150451768, - 201150516739, - 201150533289, - 201150548146, - 201150647985, - 201150650378, - 201150793312, - 201150872150, - 201150921271, - 201151296487, - 201151458889, - 201151510446, - 201151593953, - 201151616245, - 201151845956, - 201151869870, - 201152054617, - 201152154482, - 201152184337, - 201152228476, - 201152336491, - 201152636067, - 201152851954, - 201152994061, - 201153086752, - 201153094925, - 201153260339, - 201153506778, - 201153508619, - 201153590337, - 201154004771, - 201154322032, - 201154404977, - 201154505875, - 201154554795, - 201154558329, - 201154566231, - 201154962800, - 201155018765, - 201155072426, - 201155110000, - 201155215891, - 201155394107, - 201155449375, - 201155465556, - 201155512282, - 201155540425, - 201155581701, - 201155617074, - 201155633622, - 201155705126, - 201155883321, - 201156012567, - 201156265716, - 201156422481, - 201156839185, - 201156894666, - 201156941320, - 201157009020, - 201157055175, - 201157121939, - 201157347771, - 201157566765, - 201157693835, - 201158232008, - 201158313756, - 201158342680, - 201158601956, - 201158680006, - 201158913381, - 201158937603, - 201159109401, - 201159430166, - 201159519690, - 201159555233, - 201159775543, - 201200008264, - 201200205662, - 201200225120, - 201200240122, - 201200360155, - 201200395648, - 201200520512, - 201200622072, - 201200622129, - 201200678667, - 201200751933, - 201200757011, - 201200811161, - 201200999580, - 201201025700, - 201201155000, - 201201294180, - 201201312691, - 201201383512, - 201201421326, - 201201491025, - 201201621622, - 201201840871, - 201202000888, - 201202211450, - 201202530513, - 201202665435, - 201202912341, - 201203014151, - 201203039750, - 201203181372, - 201203456879, - 201203477332, - 201204023121, - 201204281981, - 201204514017, - 201204688081, - 201204855400, - 201204977751, - 201205000292, - 201205031905, - 201205686247, - 201205759040, - 201206017464, - 201206600861, - 201206975332, - 201207121802, - 201207372344, - 201207616444, - 201207750441, - 201208085263, - 201208414347, - 201208977177, - 201210023938, - 201210583591, - 201210588038, - 201210732122, - 201210818176, - 201210945113, - 201211066299, - 201211079908, - 201211161032, - 201211795422, - 201211986162, - 201212145380, - 201212258721, - 201212479538, - 201220444133, - 201220612822, - 201220724766, - 201220820976, - 201220914219, - 201221041254, - 201221138834, - 201221212426, - 201221212824, - 201221278704, - 201221280828, - 201221328517, - 201221408219, - 201221732389, - 201221800122, - 201221954550, - 201222143516, - 201222278308, - 201222282205, - 201222332047, - 201222517257, - 201222620610, - 201222695023, - 201222748994, - 201222781707, - 201222967787, - 201222971467, - 201223234257, - 201223336884, - 201223376686, - 201223401519, - 201223456731, - 201223521664, - 201223596905, - 201223671633, - 201223705456, - 201223838760, - 201223874421, - 201223940650, - 201224050760, - 201224053907, - 201224213162, - 201224217248, - 201224236042, - 201224353363, - 201224380088, - 201224483706, - 201224508493, - 201224535248, - 201224661061, - 201224752065, - 201224825057, - 201224911013, - 201224927485, - 201224970278, - 201224971527, - 201225001313, - 201225015388, - 201225294141, - 201225301553, - 201225328559, - 201225460762, - 201225570507, - 201225656181, - 201225958509, - 201226262906, - 201226291683, - 201226315730, - 201226416059, - 201226461243, - 201226595175, - 201226655253, - 201226672939, - 201226757626, - 201226782942, - 201226790797, - 201226965492, - 201226994629, - 201227070538, - 201227314954, - 201227757571, - 201227831100, - 201227885100, - 201228030501, - 201228216918, - 201228781347, - 201228922343, - 201228946285, - 201229082850, - 201229123460, - 201229974967, - 201270550493, - 201270565699, - 201270626113, - 201271122314, - 201271132209, - 201271133956, - 201271160173, - 201271401468, - 201272021184, - 201272072854, - 201272336635, - 201272649581, - 201272939093, - 201273024547, - 201273073912, - 201273114754, - 201273170033, - 201273273705, - 201273808399, - 201273888510, - 201273943548, - 201274050210, - 201274206995, - 201274302911, - 201274527249, - 201274768678, - 201274793455, - 201274842863, - 201275200924, - 201275298194, - 201275610030, - 201275624989, - 201275662461, - 201275668382, - 201275901512, - 201276330019, - 201276624302, - 201276766553, - 201277014277, - 201277117926, - 201277131373, - 201277606290, - 201277740069, - 201277773181, - 201277855345, - 201277862323, - 201278119893, - 201278324075, - 201278378190, - 201278539943, - 201278956638, - 201279236054, - 201279296936, - 201279803133, - 201279872337, - 201279920962, - 201280024389, - 201280256821, - 201280433297, - 201280832425, - 201280838169, - 201281011857, - 201281181008, - 201281659132, - 201281802541, - 201281898421, - 201282199565, - 201282427635, - 201283170305, - 201283329751, - 201283991212, - 201284350745, - 201284436627, - 201284601547, - 201285060920, - 201285686701, - 201285980741, - 201286065056, - 201286254841, - 201287277734, - 201287585360, - 201287839817, - 201288006876, - 201288090780, - 201288199133, - 201288326620, - 201288446043, - 201288496608, - 201288863470, - 201289006333, - 201289354010, - 201289488182, - 201289723337, - 201289723730, - 201289920270, - 201500085192, - 201500263335, - 201500567444, - 201500791104, - 201500888614, - 201501355877, - 201501538118, - 201501602948, - 201501877880, - 201503227949, - 201507255344, - 201507416444, - 201508325183, - 201550132936, - 201550707584, - 201550801300, - 201550817512, - 201550861194, - 201550919395, - 201551141835, - 201551233318, - 201551418313, - 201551421493, - 201551465551, - 201551500674, - 201551630844, - 201551980169, - 201553022775, - 201553077785, - 201553222768, - 201553324455, - 201553335619, - 201553540894, - 201553684030, - 201553806016, - 201553996793, - 201554435301, - 201554666842, - 201554752044, - 201555000205, - 201555116452, - 201555181159, - 201555310975, - 201555320344, - 201555402805, - 201555408958, - 201555577228, - 201555583558, - 201555604325, - 201555791055, - 201555888091, - 201555944650, - 201556206194, - 201556754333, - 201557454447, - 201557567007, - 201557770122, - 201558550454, - 201559170967, - 201559975610, - 21142703233 - ]; } diff --git a/lib/controller/functions/device_info.dart b/lib/controller/functions/device_info.dart index 93bd4a6..727f842 100644 --- a/lib/controller/functions/device_info.dart +++ b/lib/controller/functions/device_info.dart @@ -29,22 +29,19 @@ class DeviceHelper { throw UnsupportedError('Unsupported platform'); } - // Extract relevant device information - final String deviceId = Platform.isAndroid - ? deviceData['fingerprint'] ?? 'unknown' - : deviceData['identifierForVendor'] ?? 'unknown'; + String deviceId = 'unknown'; + if (Platform.isAndroid) { + deviceId = deviceData['fingerprint'] ?? 'unknown'; + } else if (Platform.isIOS) { + deviceId = deviceData['identifierForVendor'] ?? 'unknown'; + } else if (Platform.isMacOS) { + deviceId = deviceData['systemGUID'] ?? 'unknown'; + } final String deviceModel = deviceData['model'] ?? 'unknown'; - final String osVersion = Platform.isAndroid - ? deviceData['version']['release'] ?? 'unknown' - : deviceData['systemVersion'] ?? 'unknown'; - // Log the extracted information - - // Generate and return the encrypted fingerprint - final String fingerprint = '${deviceId}_${deviceModel}_$osVersion'; - - // print(EncryptionHelper.instance.encryptData(fingerprint)); + final String fingerprint = '${deviceId}_$deviceModel'; + print(fingerprint); return (fingerprint); } catch (e) { throw Exception('Failed to generate device fingerprint'); diff --git a/lib/debug_jwt.dart b/lib/debug_jwt.dart new file mode 100644 index 0000000..df5f479 --- /dev/null +++ b/lib/debug_jwt.dart @@ -0,0 +1,22 @@ +import 'package:sefer_admin1/controller/functions/encrypt_decrypt.dart'; +import 'package:sefer_admin1/constant/info.dart'; + +void main() { + String testJwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYWRtaW4ifQ.signature"; + print("Original: $testJwt"); + + String encrypted = c(testJwt); + print("Encrypted: $encrypted"); + + String decrypted = r(encrypted); + print("Decrypted: $decrypted"); + + String split = decrypted.split(AppInformation.addd)[0]; + print("Split: $split"); + + if (testJwt == split) { + print("✅ Match!"); + } else { + print("❌ Mismatch!"); + } +} diff --git a/lib/main.dart b/lib/main.dart index 971cb55..503206c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,6 +8,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:sefer_admin1/views/auth/login_page.dart'; +import 'package:sefer_admin1/views/auth/register_page.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'controller/firebase/firbase_messge.dart'; import 'controller/functions/encrypt_decrypt.dart'; @@ -62,7 +63,12 @@ class MainApp extends StatelessWidget { Widget build(BuildContext context) { return GetMaterialApp( debugShowCheckedModeBanner: false, - home: AdminLoginPage(), + initialRoute: '/login', + getPages: [ + GetPage(name: '/login', page: () => const AdminLoginPage()), + GetPage(name: '/register', page: () => const RegisterPage()), + ], + home: const AdminLoginPage(), ); } } diff --git a/lib/views/admin/admin_home_page.dart b/lib/views/admin/admin_home_page.dart index 5058f49..6a98fad 100644 --- a/lib/views/admin/admin_home_page.dart +++ b/lib/views/admin/admin_home_page.dart @@ -13,6 +13,7 @@ import '../../controller/admin/static_controller.dart'; import '../../controller/functions/crud.dart'; import '../../controller/notification_controller.dart'; import '../../main.dart'; +import '../../print.dart'; import '../invoice/invoice_list_page.dart'; import 'captain/captain.dart'; import 'captain/syrian_driver_not_active.dart'; @@ -28,6 +29,8 @@ import 'rides/ride_lookup_page.dart'; import 'server/monitor_server_page.dart'; import 'static/static.dart'; import 'wallet/wallet.dart'; +import 'staff/add_staff_page.dart'; +import 'staff/pending_admins_page.dart'; class AdminHomePage extends StatefulWidget { const AdminHomePage({super.key}); @@ -69,10 +72,16 @@ class _AdminHomePageState extends State duration: const Duration(seconds: 2), )..repeat(reverse: true); - String myPhone = box.read(BoxName.adminPhone).toString(); - isSuperAdmin = myPhone == '201023248456' || - myPhone == '963992952235' || - myPhone == '963942542053'; + final String role = box.read('admin_role')?.toString() ?? 'admin'; + final String myPhone = box.read(BoxName.adminPhone)?.toString() ?? ''; + + // التحقق من الصلاحيات: إما عن طريق الدور أو عن طريق قائمة أرقام السوبر أدمن التقليدية + isSuperAdmin = (role == 'super_admin') || + (myPhone == '201023248456' || + myPhone == '963992952235' || + myPhone == '963942542053'); + + Log.print('AdminHomePage: role=$role, isSuperAdmin=$isSuperAdmin'); dashboardController = Get.put(DashboardController()); } @@ -760,6 +769,8 @@ class _AdminHomePageState extends State const Color(0xFF80CBC4), () => Get.to(() => InvoiceListPage())), ActionItem('الموظفون', Icons.badge_rounded, const Color(0xFFB0BEC5), () => Get.to(() => EmployeePage())), + ActionItem('موافقة المشرفين', Icons.how_to_reg_rounded, _accent, + () => Get.to(() => const PendingAdminsPage())), ], ), if (isSuperAdmin) @@ -804,19 +815,37 @@ class _AdminHomePageState extends State ))), ], ), + if (isSuperAdmin) + ActionCategory( + title: 'إدارة الكوادر', + items: [ + ActionItem( + 'إضافة مدير', + Icons.admin_panel_settings_rounded, + _accent, + () => Get.to(() => const AddStaffPage(role: 'admin')), + ), + ActionItem( + 'إضافة خدمة عملاء', + Icons.support_agent_rounded, + _info, + () => Get.to(() => const AddStaffPage(role: 'service')), + ), + ], + ), ]; } List> _getDetailedStats( dynamic data, DashboardController controller) { return [ - // if (isSuperAdmin) - // { - // 'title': 'رصيد الرسائل', - // 'value': controller.creditSMS, - // 'icon': Icons.sms_rounded, - // 'color': _info, - // }, + if (isSuperAdmin) + { + 'title': 'رصيد الرسائل', + 'value': controller.creditSMS, + 'icon': Icons.sms_rounded, + 'color': _info, + }, { 'title': 'مكتملة', 'value': data['completed_rides'], diff --git a/lib/views/admin/drivers/driver_gift_check_page.dart b/lib/views/admin/drivers/driver_gift_check_page.dart index dedd222..941dc88 100644 --- a/lib/views/admin/drivers/driver_gift_check_page.dart +++ b/lib/views/admin/drivers/driver_gift_check_page.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:sefer_admin1/controller/functions/crud.dart'; -import 'package:sefer_admin1/controller/functions/wallet.dart'; // تأكد من المسار +import 'package:sefer_admin1/controller/functions/wallet.dart'; + +import '../../../constant/links.dart'; // تأكد من المسار // --- Controller: المسؤول عن المنطق (البحث، الفحص، الإضافة) --- class DriverGiftCheckerController extends GetxController { @@ -25,8 +27,7 @@ class DriverGiftCheckerController extends GetxController { Future fetchDriverCache() async { try { final response = await CRUD().post( - link: - 'https://api.intaleq.xyz/intaleq/Admin/driver/getDriverGiftPayment.php', + link: '${AppLink.server}/Admin/driver/getDriverGiftPayment.php', payload: {'phone': phoneController.text.trim()}, ); // print('response: ${response}'); @@ -55,7 +56,17 @@ class DriverGiftCheckerController extends GetxController { try { // الخطوة 1: استخراج الـ ID بناءً على رقم الهاتف var driver = driversCache.firstWhere( - (d) => d['phone'].toString().contains(phoneInput), + (d) { + String dbPhone = + d['phone'].toString().replaceAll(RegExp(r'[^0-9]'), ''); + String inputPhone = phoneInput.replaceAll(RegExp(r'[^0-9]'), ''); + // قارن آخر 9 أرقام لتجاوز مشكلة 09 مقابل 963 + if (dbPhone.length >= 9 && inputPhone.length >= 9) { + return dbPhone.substring(dbPhone.length - 9) == + inputPhone.substring(inputPhone.length - 9); + } + return dbPhone == inputPhone; + }, orElse: () => null, ); diff --git a/lib/views/admin/drivers/driver_tracker_screen.dart b/lib/views/admin/drivers/driver_tracker_screen.dart index 1384266..e64c76a 100644 --- a/lib/views/admin/drivers/driver_tracker_screen.dart +++ b/lib/views/admin/drivers/driver_tracker_screen.dart @@ -9,6 +9,7 @@ import 'package:sefer_admin1/constant/links.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../../constant/box_name.dart'; +import '../../../controller/functions/crud.dart'; import '../../../main.dart'; class IntaleqTrackerScreen extends StatefulWidget { @@ -107,12 +108,17 @@ class _IntaleqTrackerScreenState extends State try { String updateUrl = "${_baseDir}getUpdatedLocationForAdmin.php?mode=${isLiveMode ? 'live' : 'day'}"; - await http.get(Uri.parse(updateUrl)); + print("📡 Calling Update URL: $updateUrl"); + var responseUpdate = await CRUD().post(link: updateUrl, payload: {}); + print("📡 Update Response: $responseUpdate"); String v = DateTime.now().millisecondsSinceEpoch.toString(); - final responseLive = - await http.get(Uri.parse("${_baseDir}locations_live.json?v=$v")); + String liveUrl = "${_baseDir}locations_live.json?v=$v"; + print("📡 Calling Live JSON URL: $liveUrl"); + final responseLive = await http.get(Uri.parse(liveUrl)); + print( + "📡 Live JSON Response (${responseLive.statusCode}): ${responseLive.body.length > 100 ? responseLive.body.substring(0, 100) : responseLive.body}"); if (responseLive.statusCode == 200) { final data = json.decode(responseLive.body); List drivers = (data is Map && data.containsKey('drivers')) @@ -125,8 +131,11 @@ class _IntaleqTrackerScreenState extends State }); } - final responseDay = - await http.get(Uri.parse("${_baseDir}locations_day.json?v=$v")); + String dayUrl = "${_baseDir}locations_day.json?v=$v"; + print("📡 Calling Day JSON URL: $dayUrl"); + final responseDay = await http.get(Uri.parse(dayUrl)); + print( + "📡 Day JSON Response (${responseDay.statusCode}): ${responseDay.body.length > 100 ? responseDay.body.substring(0, 100) : responseDay.body}"); if (responseDay.statusCode == 200) { final data = json.decode(responseDay.body); List drivers = (data is Map && data.containsKey('drivers')) diff --git a/lib/views/admin/enceypt/fingerprint_migration.dart b/lib/views/admin/enceypt/fingerprint_migration.dart index 532d0da..13ca834 100644 --- a/lib/views/admin/enceypt/fingerprint_migration.dart +++ b/lib/views/admin/enceypt/fingerprint_migration.dart @@ -20,7 +20,9 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:sefer_admin1/controller/functions/encrypt_decrypt.dart' as X; +import '../../../constant/char_map.dart'; import '../../../constant/links.dart'; import '../../../controller/functions/crud.dart'; import '../../../controller/functions/encrypt_decrypt.dart'; @@ -240,8 +242,7 @@ class _FingerprintMigrationToolState extends State { Container( child: TextButton( onPressed: () { - print(EncryptionHelper.instance.decryptData( - 'dab40749cdecbfddf4696566448b384f0d272705b08b4ff779e085fbf3257026')); + print(EncryptionHelper.instance.decryptData('hbgbitbXrXrBr')); }, child: Text( "Decrypt Test", @@ -259,6 +260,16 @@ class _FingerprintMigrationToolState extends State { ), ), ), + Container( + child: TextButton( + onPressed: () { + print(r('hbgbitbXrXrBr')); + }, + child: Text( + "decrypt X.r", + ), + ), + ), const SizedBox(height: 24), diff --git a/lib/views/admin/packages.dart b/lib/views/admin/packages.dart index 201afdf..4e957aa 100644 --- a/lib/views/admin/packages.dart +++ b/lib/views/admin/packages.dart @@ -537,11 +537,19 @@ class PackageController extends GetxController { fetchPackages() async { isLoading.value = true; var response = await CRUD().get(link: AppLink.getPackages, payload: {}); - if (response != 'failure') { - var jsonData = jsonDecode(response); - packages = jsonData['message']; + + if (response is String && (response == 'failure' || response == 'token_expired')) { + isLoading.value = false; + return; + } + + try { + var jsonData = response is String ? jsonDecode(response) : response; + packages = jsonData['message'] ?? []; + Log.print('✅ Decoded packages: ${packages.length} items'); update(); - Log.print('jsonData: $jsonData'); + } catch (e) { + Log.print('❌ Error parsing packages: $e'); } isLoading.value = false; } diff --git a/lib/views/admin/staff/add_staff_page.dart b/lib/views/admin/staff/add_staff_page.dart new file mode 100644 index 0000000..057bf89 --- /dev/null +++ b/lib/views/admin/staff/add_staff_page.dart @@ -0,0 +1,195 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../../controller/admin/staff_controller.dart'; + +class AddStaffPage extends StatelessWidget { + final String role; // 'admin' or 'service' + const AddStaffPage({super.key, required this.role}); + + @override + Widget build(BuildContext context) { + final controller = Get.put(StaffController()); + controller.selectedRole = role; + + const Color bgColor = Color(0xFF0D1117); + const Color inputColor = Color(0xFF161B22); + const Color accentColor = Color(0xFF00D4AA); + + return Scaffold( + backgroundColor: bgColor, + appBar: AppBar( + title: Text(role == 'admin' ? "إضافة مدير جديد" : "إضافة موظف خدمة عملاء"), + backgroundColor: bgColor, + elevation: 0, + ), + body: SingleChildScrollView( + padding: const EdgeInsets.all(24), + child: Form( + key: controller.formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("المعلومات الأساسية"), + const SizedBox(height: 16), + _buildTextField( + controller: controller.nameController, + label: "الاسم الكامل", + icon: Icons.person_outline, + fillColor: inputColor, + ), + const SizedBox(height: 16), + _buildTextField( + controller: controller.phoneController, + label: "رقم الهاتف", + icon: Icons.phone_android_outlined, + fillColor: inputColor, + keyboardType: TextInputType.phone, + ), + const SizedBox(height: 16), + _buildTextField( + controller: controller.emailController, + label: "البريد الإلكتروني", + icon: Icons.email_outlined, + fillColor: inputColor, + keyboardType: TextInputType.emailAddress, + ), + const SizedBox(height: 16), + _buildTextField( + controller: controller.passwordController, + label: "كلمة المرور", + icon: Icons.lock_outline, + fillColor: inputColor, + obscureText: true, + ), + const SizedBox(height: 24), + _buildSectionTitle("معلومات إضافية"), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: _buildDropdown( + label: "الجنس", + value: controller.selectedGender, + items: ['Male', 'Female'], + onChanged: (val) => controller.selectedGender = val!, + fillColor: inputColor, + ), + ), + const SizedBox(width: 16), + Expanded( + child: _buildTextField( + controller: controller.birthdateController, + label: "تاريخ الميلاد", + icon: Icons.calendar_today_outlined, + fillColor: inputColor, + hint: "YYYY-MM-DD", + ), + ), + ], + ), + const SizedBox(height: 40), + GetBuilder( + builder: (controller) => SizedBox( + width: double.infinity, + height: 56, + child: ElevatedButton( + onPressed: controller.isLoading ? null : () => controller.registerStaff(), + style: ElevatedButton.styleFrom( + backgroundColor: accentColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + ), + child: controller.isLoading + ? const CircularProgressIndicator(color: Colors.white) + : Text( + "حفظ البيانات", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: bgColor, + ), + ), + ), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildSectionTitle(String title) { + return Text( + title, + style: const TextStyle( + color: Color(0xFF7D8590), + fontSize: 13, + fontWeight: FontWeight.bold, + letterSpacing: 1.2, + ), + ); + } + + Widget _buildTextField({ + required TextEditingController controller, + required String label, + required IconData icon, + required Color fillColor, + String? hint, + bool obscureText = false, + TextInputType keyboardType = TextInputType.text, + }) { + return Container( + decoration: BoxDecoration( + color: fillColor, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.white.withOpacity(0.05)), + ), + child: TextFormField( + controller: controller, + obscureText: obscureText, + keyboardType: keyboardType, + style: const TextStyle(color: Colors.white), + decoration: InputDecoration( + labelText: label, + hintText: hint, + hintStyle: const TextStyle(color: Colors.white24), + labelStyle: const TextStyle(color: Colors.white54), + prefixIcon: Icon(icon, color: Colors.white38), + border: InputBorder.none, + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), + ), + validator: (val) => val == null || val.isEmpty ? "هذا الحقل مطلوب" : null, + ), + ); + } + + Widget _buildDropdown({ + required String label, + required String value, + required List items, + required Function(String?) onChanged, + required Color fillColor, + }) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: fillColor, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.white.withOpacity(0.05)), + ), + child: DropdownButtonFormField( + value: value, + dropdownColor: fillColor, + style: const TextStyle(color: Colors.white), + decoration: InputDecoration( + labelText: label, + labelStyle: const TextStyle(color: Colors.white54), + border: InputBorder.none, + ), + items: items.map((e) => DropdownMenuItem(value: e, child: Text(e))).toList(), + onChanged: onChanged, + ), + ); + } +} diff --git a/lib/views/admin/staff/pending_admins_page.dart b/lib/views/admin/staff/pending_admins_page.dart new file mode 100644 index 0000000..d8e2f57 --- /dev/null +++ b/lib/views/admin/staff/pending_admins_page.dart @@ -0,0 +1,148 @@ +import 'package:flutter/material.dart'; +import '../../../constant/links.dart'; +import '../../../controller/functions/crud.dart'; +import '../../widgets/snackbar.dart'; + +class PendingAdminsPage extends StatefulWidget { + const PendingAdminsPage({super.key}); + + @override + State createState() => _PendingAdminsPageState(); +} + +class _PendingAdminsPageState extends State { + final CRUD _crud = CRUD(); + bool _isLoading = true; + List _pendingAdmins = []; + + @override + void initState() { + super.initState(); + _fetchPendingAdmins(); + } + + Future _fetchPendingAdmins() async { + setState(() => _isLoading = true); + try { + final response = await _crud.post( + link: '${AppLink.server}/Admin/auth/list_pending.php', + ); + if (response != 'failure') { + setState(() { + _pendingAdmins = response['message'] ?? []; + }); + } + } catch (e) { + mySnackeBarError('فشل في جلب البيانات: $e'); + } finally { + setState(() => _isLoading = false); + } + } + + Future _handleAction(String adminId, String action) async { + try { + final response = await _crud.post( + link: '${AppLink.server}/Admin/auth/approve_admin.php', + payload: { + 'admin_id': adminId, + 'action': action, + }, + ); + if (response != 'failure') { + mySnackbarSuccess('تم تنفيذ الإجراء بنجاح'); + _fetchPendingAdmins(); // تحديث القائمة + } + } catch (e) { + mySnackeBarError('حدث خطأ: $e'); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF0A0D14), + appBar: AppBar( + title: const Text('طلبات الانضمام المعلقة', style: TextStyle(fontWeight: FontWeight.bold)), + backgroundColor: const Color(0xFF161D2E), + elevation: 0, + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator(color: Color(0xFF00E5FF))) + : _pendingAdmins.isEmpty + ? _buildEmptyState() + : _buildList(), + ); + } + + Widget _buildEmptyState() { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.person_search_rounded, size: 80, color: Colors.grey[800]), + const SizedBox(height: 16), + const Text('لا توجد طلبات معلقة حالياً', style: TextStyle(color: Colors.grey)), + ], + ), + ); + } + + Widget _buildList() { + return ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: _pendingAdmins.length, + itemBuilder: (context, index) { + final admin = _pendingAdmins[index]; + return Container( + margin: const EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: const Color(0xFF161D2E), + borderRadius: BorderRadius.circular(16), + border: Border.all(color: const Color(0xFF1F2D4A)), + ), + child: Column( + children: [ + ListTile( + contentPadding: EdgeInsets.zero, + leading: const CircleAvatar( + backgroundColor: Color(0xFF1F2D4A), + child: Icon(Icons.person, color: Color(0xFF00E5FF)), + ), + title: Text(admin['name'] ?? 'بدون اسم', style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + subtitle: Text(admin['phone'] ?? 'بدون رقم', style: const TextStyle(color: Colors.grey)), + trailing: Text( + admin['created_at']?.split(' ')[0] ?? '', + style: const TextStyle(color: Colors.grey, fontSize: 12), + ), + ), + const Divider(color: Color(0xFF1F2D4A), height: 24), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () => _handleAction(admin['id'], 'rejected'), + style: TextButton.styleFrom(foregroundColor: Colors.redAccent), + child: const Text('رفض'), + ), + const SizedBox(width: 8), + ElevatedButton( + onPressed: () => _handleAction(admin['id'], 'approved'), + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF00E5FF), + foregroundColor: Colors.black, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: const Text('موافقة', style: TextStyle(fontWeight: FontWeight.bold)), + ), + ], + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/views/auth/login_page.dart b/lib/views/auth/login_page.dart index 580b4c6..87ed194 100644 --- a/lib/views/auth/login_page.dart +++ b/lib/views/auth/login_page.dart @@ -6,6 +6,7 @@ import '../../controller/auth/login_controller.dart'; import '../../controller/auth/otp_helper.dart'; import '../../controller/functions/crud.dart'; import '../../print.dart'; +import '../admin/admin_home_page.dart'; // ─── Colors (نفس نظام الألوان المستخدم في التطبيق) ────────────────────────── class _C { @@ -31,30 +32,28 @@ class AdminLoginPage extends StatefulWidget { class _AdminLoginPageState extends State with SingleTickerProviderStateMixin { final _phoneController = TextEditingController(); + final _passwordController = TextEditingController(); final _formKey = GlobalKey(); bool _isLoading = false; late final AnimationController _glowCtrl; late final Animation _glowAnim; - // ─── Logic (بدون تغيير) ──────────────────────────────────────────────────── Future _submit() async { - final allowedPhones = Env.ALLOWED_ADMIN_PHONES; - Log.print('allowedPhones: ${allowedPhones}'); - allowedPhones.toString().split(','); + final password = _passwordController.text.trim(); - final phone = _phoneController.text.trim(); - - if (!allowedPhones.contains(phone)) { - Get.snackbar('رفض الدخول', 'رقم الهاتف غير مخوّل بالدخول إلى الإدارة'); + if (password.isEmpty) { + Get.snackbar('خطأ', 'يرجى إدخال كلمة المرور'); return; } setState(() => _isLoading = true); - final otpSent = await OtpHelper.sendOtp(phone); - if (otpSent) { - Get.to(() => OtpVerificationAdmin(phone: phone)); + final otpHelper = Get.find(); + bool success = await otpHelper.loginWithPassword(password); + + if (success) { + Get.offAll(() => const AdminHomePage()); } setState(() => _isLoading = false); @@ -75,7 +74,7 @@ class _AdminLoginPageState extends State } void _initializeToken() async { - await CRUD().getJWT(); + // await CRUD().getJWT(); } @override @@ -168,7 +167,7 @@ class _AdminLoginPageState extends State ), const SizedBox(height: 8), const Text( - 'أدخل رقم هاتفك للمتابعة', + 'أدخل كلمة المرور للمتابعة', style: TextStyle( color: _C.textSec, fontSize: 14, @@ -195,14 +194,15 @@ class _AdminLoginPageState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // ── Field label ───────────────────────────── + const SizedBox(height: 20), + // ── Field label (Password) ───────────────────────────── const Row( children: [ - Icon(Icons.phone_android_rounded, + Icon(Icons.lock_outline_rounded, color: _C.accent, size: 16), SizedBox(width: 8), Text( - 'رقم الهاتف', + 'كلمة المرور', style: TextStyle( color: _C.textSec, fontSize: 13, @@ -213,28 +213,19 @@ class _AdminLoginPageState extends State ], ), const SizedBox(height: 10), - - // ── Phone field ───────────────────────────── + // ── Password field ───────────────────────────── TextFormField( - controller: _phoneController, - keyboardType: TextInputType.phone, - textDirection: TextDirection.ltr, + controller: _passwordController, + obscureText: true, style: const TextStyle( color: _C.textPrimary, fontSize: 16, - fontFamily: 'monospace', - letterSpacing: 1.2, ), decoration: InputDecoration( - hintText: '+963 XXX XXX XXX', - hintStyle: const TextStyle( - color: _C.textSec, - fontSize: 14, - letterSpacing: 0.5), + hintText: '••••••••', + hintStyle: const TextStyle(color: _C.textSec), filled: true, fillColor: _C.inputBg, - prefixIcon: const Icon(Icons.dialpad_rounded, - color: _C.accentDim, size: 20), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, @@ -249,24 +240,12 @@ class _AdminLoginPageState extends State borderSide: const BorderSide( color: _C.accent, width: 1.5), ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(14), - borderSide: const BorderSide( - color: _C.error, width: 1), - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(14), - borderSide: const BorderSide( - color: _C.error, width: 1.5), - ), contentPadding: const EdgeInsets.symmetric( horizontal: 16, vertical: 16), - errorStyle: const TextStyle( - color: _C.error, fontSize: 12), ), validator: (value) { if (value == null || value.isEmpty) { - return 'الرجاء إدخال رقم الهاتف'; + return 'الرجاء إدخال كلمة المرور'; } return null; }, @@ -296,6 +275,21 @@ class _AdminLoginPageState extends State const SizedBox(height: 32), + // ── Register Button ───────────────────────────────── + TextButton( + onPressed: () => Get.toNamed('/register'), + child: const Text( + 'ليس لديك حساب؟ طلب انضمام', + style: TextStyle( + color: _C.accent, + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + ), + + const SizedBox(height: 16), + // ── Footer ────────────────────────────────────────── Row( mainAxisAlignment: MainAxisAlignment.center, @@ -435,8 +429,8 @@ class _SubmitButtonState extends State<_SubmitButton> children: [ Icon(Icons.send_rounded, color: Colors.white, size: 18), SizedBox(width: 10), - Text( - 'إرسال رمز التحقق', + const Text( + 'تسجيل الدخول', style: TextStyle( color: Colors.white, fontSize: 16, diff --git a/lib/views/auth/register_page.dart b/lib/views/auth/register_page.dart new file mode 100644 index 0000000..3a5ded4 --- /dev/null +++ b/lib/views/auth/register_page.dart @@ -0,0 +1,181 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import '../../constant/box_name.dart'; +import '../../constant/links.dart'; +import '../../main.dart'; +import '../../views/widgets/snackbar.dart'; +import '../../controller/functions/crud.dart'; + +class _C { + static const bg = Color(0xFF0A0D14); + static const card = Color(0xFF161D2E); + static const accent = Color(0xFF00E5FF); + static const textPrimary = Color(0xFFE8F0FE); + static const textSec = Color(0xFF7A8BAA); + static const inputBg = Color(0xFF0C1120); +} + +class RegisterPage extends StatefulWidget { + const RegisterPage({super.key}); + + @override + State createState() => _RegisterPageState(); +} + +class _RegisterPageState extends State { + final _nameController = TextEditingController(); + final _phoneController = TextEditingController(); + final _passwordController = TextEditingController(); + final _formKey = GlobalKey(); + bool _isLoading = false; + + Future _register() async { + if (!_formKey.currentState!.validate()) return; + + setState(() => _isLoading = true); + + try { + final fingerprint = box.read(BoxName.fingerPrint); + final response = await CRUD().post( + link: '${AppLink.server}/Admin/auth/register.php', + payload: { + 'name': _nameController.text.trim(), + 'phone': _phoneController.text.trim(), + 'password': _passwordController.text.trim(), + 'fingerprint': fingerprint, + }, + ); + + if (response != 'failure') { + mySnackbarSuccess(response['message'] ?? 'تم تقديم طلبك بنجاح'); + Get.back(); // العودة لصفحة الدخول + } + } catch (e) { + mySnackeBarError('حدث خطأ أثناء التسجيل: $e'); + } finally { + setState(() => _isLoading = false); + } + } + + @override + void dispose() { + _nameController.dispose(); + _phoneController.dispose(); + _passwordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: _C.bg, + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios_new_rounded, color: _C.accent), + onPressed: () => Get.back(), + ), + ), + body: Center( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 28), + child: Form( + key: _formKey, + child: Column( + children: [ + const Icon(Icons.person_add_rounded, color: _C.accent, size: 64), + const SizedBox(height: 24), + const Text( + 'طلب انضمام جديد', + style: TextStyle( + color: _C.textPrimary, + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + const Text( + 'سيتم مراجعة طلبك من قبل الإدارة', + style: TextStyle(color: _C.textSec, fontSize: 14), + ), + const SizedBox(height: 40), + _buildCard(), + const SizedBox(height: 32), + ], + ), + ), + ), + ), + ); + } + + Widget _buildCard() { + return Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: _C.card, + borderRadius: BorderRadius.circular(24), + border: Border.all(color: _C.accent.withAlpha(25)), // 0.1 * 255 ≈ 25 + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildField('الاسم الكامل', _nameController, Icons.person_outline), + const SizedBox(height: 20), + _buildField('رقم الهاتف', _phoneController, Icons.phone_android, isPhone: true), + const SizedBox(height: 20), + _buildField('كلمة المرور', _passwordController, Icons.lock_outline, isPass: true), + const SizedBox(height: 32), + _isLoading + ? const Center(child: CircularProgressIndicator(color: _C.accent)) + : ElevatedButton( + onPressed: _register, + style: ElevatedButton.styleFrom( + backgroundColor: _C.accent, + foregroundColor: Colors.black, + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(14), + ), + ), + child: const Text('إرسال الطلب', style: TextStyle(fontWeight: FontWeight.bold)), + ), + ], + ), + ); + } + + Widget _buildField(String label, TextEditingController ctrl, IconData icon, + {bool isPhone = false, bool isPass = false}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(icon, color: _C.accent, size: 16), + const SizedBox(width: 8), + Text(label, style: const TextStyle(color: _C.textSec, fontSize: 13)), + ], + ), + const SizedBox(height: 8), + TextFormField( + controller: ctrl, + obscureText: isPass, + keyboardType: isPhone ? TextInputType.phone : TextInputType.text, + style: const TextStyle(color: _C.textPrimary), + decoration: InputDecoration( + filled: true, + fillColor: _C.inputBg, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: BorderSide.none, + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), + ), + validator: (val) => val == null || val.isEmpty ? 'هذا الحقل مطلوب' : null, + ), + ], + ); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 13947f7..a2f221b 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -14,7 +14,6 @@ import flutter_image_compress_macos import flutter_secure_storage_macos import google_sign_in_ios import local_auth_darwin -import path_provider_foundation import sqflite_darwin import url_launcher_macos @@ -28,7 +27,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin")) - PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 5022cd0..3aeb2b1 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -134,9 +134,6 @@ PODS: - nanopb/encode (= 3.30910.0) - nanopb/decode (3.30910.0) - nanopb/encode (3.30910.0) - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - PromisesObjC (2.4.0) - PromisesSwift (2.4.0): - PromisesObjC (= 2.4.0) @@ -157,7 +154,6 @@ DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral`) - google_sign_in_ios (from `Flutter/ephemeral/.symlinks/plugins/google_sign_in_ios/darwin`) - local_auth_darwin (from `Flutter/ephemeral/.symlinks/plugins/local_auth_darwin/darwin`) - - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) @@ -204,8 +200,6 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/google_sign_in_ios/darwin local_auth_darwin: :path: Flutter/ephemeral/.symlinks/plugins/local_auth_darwin/darwin - path_provider_foundation: - :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin sqflite_darwin: :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin url_launcher_macos: @@ -215,7 +209,7 @@ SPEC CHECKSUMS: AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73 AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 - file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31 + file_selector_macos: 9e9e068e90ebee155097d00e89ae91edb2374db7 Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e firebase_core: 7667f880631ae8ad10e3d6567ab7582fe0682326 firebase_crashlytics: af8dce4a4f3b2b1556bf51043623060a5fc7eca7 @@ -230,20 +224,19 @@ SPEC CHECKSUMS: FirebaseSessions: b9a92c1c51bbb81e78fc3142cda6d925d700f8e7 flutter_image_compress_macos: e68daf54bb4bf2144c580fd4d151c949cbf492f0 flutter_secure_storage_macos: 7f45e30f838cf2659862a4e4e3ee1c347c2b3b54 - FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 google_sign_in_ios: b48bb9af78576358a168361173155596c845f0b9 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleSignIn: ce8c89bb9b37fb624b92e7514cc67335d1e277e4 GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 - local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19 + local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 - path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 - url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 + url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009 diff --git a/pubspec.lock b/pubspec.lock index 3c3bb62..40e9038 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f + sha256: "8d7ff3948166b8ec5da0fbb5962000926b8e02f2ed9b3e51d1738905fbd4c98d" url: "https://pub.dev" source: hosted - version: "85.0.0" + version: "93.0.0" _flutterfire_internals: dependency: transitive description: @@ -21,18 +21,18 @@ packages: dependency: transitive description: name: analyzer - sha256: "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d" + sha256: de7148ed2fcec579b19f122c1800933dfa028f6d9fd38a152b04b1516cec120b url: "https://pub.dev" source: hosted - version: "7.7.1" + version: "10.0.1" archive: dependency: transitive description: name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff url: "https://pub.dev" source: hosted - version: "4.0.7" + version: "4.0.9" args: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.13.1" boolean_selector: dependency: transitive description: @@ -69,50 +69,34 @@ packages: dependency: transitive description: name: build - sha256: "51dc711996cbf609b90cbe5b335bbce83143875a9d58e4b5c6d3c4f684d3dda7" + sha256: a156715e7cd728130c592f30552575908aae5b100005fbc1f0fb16b3c03a3d10 url: "https://pub.dev" source: hosted - version: "2.5.4" + version: "4.0.6" build_config: dependency: transitive description: name: build_config - sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" + sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.3.0" build_daemon: dependency: transitive description: name: build_daemon - sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" + sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957 url: "https://pub.dev" source: hosted - version: "4.0.4" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - sha256: ee4257b3f20c0c90e72ed2b57ad637f694ccba48839a821e87db762548c22a62 - url: "https://pub.dev" - source: hosted - version: "2.5.4" + version: "4.1.1" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "382a4d649addbfb7ba71a3631df0ec6a45d5ab9b098638144faf27f02778eb53" + sha256: "22fdcc3cfeb9d974d7408718c4be15ec5e9b1b350088f3a6c88f154e74dd700d" url: "https://pub.dev" source: hosted - version: "2.5.4" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - sha256: "85fbbb1036d576d966332a3f5ce83f2ce66a40bea1a94ad2d5fc29a19a0d3792" - url: "https://pub.dev" - source: hosted - version: "9.1.2" + version: "2.14.1" built_collection: dependency: transitive description: @@ -125,18 +109,18 @@ packages: dependency: transitive description: name: built_value - sha256: "0b1b12a0a549605e5f04476031cd0bc91ead1d7c8e830773a18ee54179b3cb62" + sha256: "0730c18c770d05636a8f945c32a4d7d81cb6e0f0148c8db4ad12e7748f7e49af" url: "https://pub.dev" source: hosted - version: "8.11.0" + version: "8.12.5" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" checked_yaml: dependency: transitive description: @@ -161,14 +145,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + url: "https://pub.dev" + source: hosted + version: "1.0.0" code_builder: dependency: transitive description: name: code_builder - sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + sha256: "6a6cab2ba4680d6423f34a9b972a4c9a94ebe1b62ecec4e1a1f2cba91fd1319d" url: "https://pub.dev" source: hosted - version: "4.10.1" + version: "4.11.1" collection: dependency: transitive description: @@ -189,18 +181,18 @@ packages: dependency: transitive description: name: cross_file - sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" url: "https://pub.dev" source: hosted - version: "0.3.4+2" + version: "0.3.5+2" crypto: dependency: transitive description: name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" dart_earcut: dependency: transitive description: @@ -213,10 +205,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb" + sha256: "29f7ecc274a86d32920b1d9cfc7502fa87220da41ec60b55f329559d5732e2b2" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.7" device_info_plus: dependency: "direct main" description: @@ -237,18 +229,18 @@ packages: dependency: "direct main" description: name: dio - sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + sha256: aff32c08f92787a557dd5c0145ac91536481831a01b4648136373cddb0e64f8c url: "https://pub.dev" source: hosted - version: "5.8.0+1" + version: "5.9.2" dio_web_adapter: dependency: transitive description: name: dio_web_adapter - sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + sha256: "2f9e64323a7c3c7ef69567d5c800424a11f8337b8b228bad02524c9fb3c1f340" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" encrypt: dependency: "direct main" description: @@ -261,26 +253,26 @@ packages: dependency: "direct main" description: name: envied - sha256: a4e2b1d0caa479b5d61332ae516518c175a6d09328a35a0bc0a53894cc5d7e4d + sha256: cac8bf0df6c53bd3c3511a6ee295ba6b86e6547df25c8c8648fc479128d2317c url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.3.4" envied_generator: dependency: "direct dev" description: name: envied_generator - sha256: "894f6c5eb624c60a1ce6f642b6fd7ec68bc3440aa6f1881837aa9acbbeade0c8" + sha256: ac7c2d0871a25a917f145a42ca6b4596b81b97d71017a511e0b3ffa60067cf75 url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.3.4" equatable: dependency: transitive description: name: equatable - sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b" url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.8" fake_async: dependency: transitive description: @@ -293,10 +285,10 @@ packages: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" file: dependency: transitive description: @@ -309,34 +301,34 @@ packages: dependency: transitive description: name: file_selector_linux - sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" + sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" url: "https://pub.dev" source: hosted - version: "0.9.3+2" + version: "0.9.4" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "8c9250b2bd2d8d4268e39c82543bacbaca0fda7d29e0728c3c4bbb7c820fd711" + sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" url: "https://pub.dev" source: hosted - version: "0.9.4+3" + version: "0.9.5" file_selector_platform_interface: dependency: transitive description: name: file_selector_platform_interface - sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85" url: "https://pub.dev" source: hosted - version: "2.6.2" + version: "2.7.0" file_selector_windows: dependency: transitive description: name: file_selector_windows - sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" + sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd" url: "https://pub.dev" source: hosted - version: "0.9.3+4" + version: "0.9.3+5" firebase_core: dependency: "direct main" description: @@ -349,10 +341,10 @@ packages: dependency: transitive description: name: firebase_core_platform_interface - sha256: "5dbc900677dcbe5873d22ad7fbd64b047750124f1f9b7ebe2a33b9ddccc838eb" + sha256: "0ecda14c1bfc9ed8cac303dd0f8d04a320811b479362a9a4efb14fd331a473ce" url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "6.0.3" firebase_core_web: dependency: transitive description: @@ -498,10 +490,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e + sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0" url: "https://pub.dev" source: hosted - version: "2.0.28" + version: "2.0.34" flutter_secure_storage: dependency: "direct main" description: @@ -568,22 +560,14 @@ packages: description: flutter source: sdk version: "0.0.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - url: "https://pub.dev" - source: hosted - version: "4.0.0" get: dependency: "direct main" description: name: get - sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 + sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" url: "https://pub.dev" source: hosted - version: "4.7.2" + version: "4.7.3" get_storage: dependency: "direct main" description: @@ -604,10 +588,10 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 + sha256: ba03d03bcaa2f6cb7bd920e3b5027181db75ab524f8891c8bc3aa603885b8055 url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.3.3" google_identity_services_web: dependency: transitive description: @@ -672,14 +656,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + hooks: + dependency: transitive + description: + name: hooks + sha256: "025f060e86d2d4c3c47b56e33caf7f93bf9283340f26d23424ebcfccf34f621e" + url: "https://pub.dev" + source: hosted + version: "1.0.3" http: dependency: "direct main" description: name: http - sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.6.0" http_multi_server: dependency: transitive description: @@ -700,10 +692,10 @@ packages: dependency: transitive description: name: image - sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce url: "https://pub.dev" source: hosted - version: "4.5.4" + version: "4.8.0" image_cropper: dependency: "direct main" description: @@ -724,74 +716,74 @@ packages: dependency: transitive description: name: image_cropper_platform_interface - sha256: "6ca6b81769abff9a4dcc3bbd3d75f5dfa9de6b870ae9613c8cd237333a4283af" + sha256: "2d8db8f4b638e448fa89a1e77cd8f053b4547472bd3ae073169e86626d03afef" url: "https://pub.dev" source: hosted - version: "7.1.0" + version: "7.2.0" image_picker: dependency: "direct main" description: name: image_picker - sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" + sha256: "91c025426c2881c551100bce834e201c835a170151545f58d17da5180ca7d9ac" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.2" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "6fae381e6af2bbe0365a5e4ce1db3959462fa0c4d234facf070746024bb80c8d" + sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f url: "https://pub.dev" source: hosted - version: "0.8.12+24" + version: "0.8.13+17" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83" + sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214" url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.1.1" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100" + sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588 url: "https://pub.dev" source: hosted - version: "0.8.12+2" + version: "0.8.13+6" image_picker_linux: dependency: transitive description: name: image_picker_linux - sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9" + sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" url: "https://pub.dev" source: hosted - version: "0.2.1+2" + version: "0.2.2" image_picker_macos: dependency: transitive description: name: image_picker_macos - sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1" + sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91" url: "https://pub.dev" source: hosted - version: "0.2.1+2" + version: "0.2.2+1" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0" + sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c" url: "https://pub.dev" source: hosted - version: "2.10.1" + version: "2.11.1" image_picker_windows: dependency: transitive description: name: image_picker_windows - sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae url: "https://pub.dev" source: hosted - version: "0.2.1+1" + version: "0.2.2" intl: dependency: "direct main" description: @@ -812,10 +804,26 @@ packages: dependency: "direct main" description: name: jailbreak_root_detection - sha256: c611229940a09785bd686364e92a40b07724926d2496c931527805101eb3da86 + sha256: "5000177b9a27428e9c47d2b98f21ab707bef5869c036f9bda4f4f95f4ad67d72" url: "https://pub.dev" source: hosted - version: "1.1.6" + version: "1.2.0+1" + jni: + dependency: transitive + description: + name: jni + sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f + url: "https://pub.dev" + source: hosted + version: "1.0.0" + jni_flutter: + dependency: transitive + description: + name: jni_flutter + sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" js: dependency: transitive description: @@ -828,10 +836,10 @@ packages: dependency: transitive description: name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.11.0" jwt_decoder: dependency: "direct main" description: @@ -852,26 +860,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" url: "https://pub.dev" source: hosted - version: "10.0.9" + version: "11.0.2" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -900,26 +908,26 @@ packages: dependency: transitive description: name: local_auth_android - sha256: "82b2bdeee2199a510d3b7716121e96a6609da86693bb0863edd8566355406b79" + sha256: a0bdfcc0607050a26ef5b31d6b4b254581c3d3ce3c1816ab4d4f4a9173e84467 url: "https://pub.dev" source: hosted - version: "1.0.50" + version: "1.0.56" local_auth_darwin: dependency: transitive description: name: local_auth_darwin - sha256: "25163ce60a5a6c468cf7a0e3dc8a165f824cabc2aa9e39a5e9fc5c2311b7686f" + sha256: "699873970067a40ef2f2c09b4c72eb1cfef64224ef041b3df9fdc5c4c1f91f49" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.6.1" local_auth_platform_interface: dependency: transitive description: name: local_auth_platform_interface - sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a" + sha256: f98b8e388588583d3f781f6806e4f4c9f9e189d898d27f0c249b93a1973dd122 url: "https://pub.dev" source: hosted - version: "1.0.10" + version: "1.1.0" local_auth_windows: dependency: transitive description: @@ -932,10 +940,10 @@ packages: dependency: transitive description: name: logger - sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3 + sha256: "25aee487596a6257655a1e091ec2ae66bc30e7af663592cc3a27e6591e05035c" url: "https://pub.dev" source: hosted - version: "2.6.2" + version: "2.7.0" logging: dependency: transitive description: @@ -948,26 +956,26 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.18" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mgrs_dart: dependency: transitive description: @@ -984,6 +992,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572" + url: "https://pub.dev" + source: hosted + version: "0.17.6" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52" + url: "https://pub.dev" + source: hosted + version: "9.3.0" package_config: dependency: transitive description: @@ -1012,18 +1036,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 + sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" url: "https://pub.dev" source: hosted - version: "2.2.17" + version: "2.3.1" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.6.0" path_provider_linux: dependency: transitive description: @@ -1052,10 +1076,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" + sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "7.0.2" platform: dependency: transitive description: @@ -1092,18 +1116,18 @@ packages: dependency: transitive description: name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" url: "https://pub.dev" source: hosted - version: "1.5.1" + version: "1.5.2" posix: dependency: transitive description: name: posix - sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" url: "https://pub.dev" source: hosted - version: "6.0.3" + version: "6.5.0" proj4dart: dependency: transitive description: @@ -1136,6 +1160,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" + record_use: + dependency: transitive + description: + name: record_use + sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + url: "https://pub.dev" + source: hosted + version: "0.6.0" secure_string_operations: dependency: "direct main" description: @@ -1168,42 +1200,42 @@ packages: dependency: transitive description: name: source_gen - sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b" + sha256: ec37cc0e6694374cbef59ed79685572c870a54ede6fa30a3e420feb3adffea02 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "4.2.3" source_span: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.2" sqflite: dependency: "direct main" description: name: sqflite - sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + sha256: "564cfed0746fe53140c23b70b308e045c3b31f17778f2f326ccb7d804ea0250a" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.2+1" sqflite_android: dependency: transitive description: name: sqflite_android - sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" + sha256: "881e28efdcc9950fd8e9bb42713dcf1103e62a2e7168f23c9338d82db13dec40" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2+3" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b" + sha256: "5e8377564d95166761a968ed96104e0569b6b6cc611faac92a36ab8a169112c3" url: "https://pub.dev" source: hosted - version: "2.5.5" + version: "2.5.6+1" sqflite_darwin: dependency: transitive description: @@ -1256,10 +1288,10 @@ packages: dependency: transitive description: name: synchronized - sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + sha256: "63896c27e81b28f8cb4e69ead0d3e8f03f1d1e5fc531a3e579cabed6a2c7c9e5" url: "https://pub.dev" source: hosted - version: "3.4.0" + version: "3.4.0+1" term_glyph: dependency: transitive description: @@ -1272,18 +1304,10 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" url: "https://pub.dev" source: hosted - version: "0.7.4" - timing: - dependency: transitive - description: - name: timing - sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" - url: "https://pub.dev" - source: hosted - version: "1.0.2" + version: "0.7.9" typed_data: dependency: transitive description: @@ -1312,34 +1336,34 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79" + sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572" url: "https://pub.dev" source: hosted - version: "6.3.16" + version: "6.3.29" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" + sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" url: "https://pub.dev" source: hosted - version: "6.3.3" + version: "6.4.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.5" url_launcher_platform_interface: dependency: transitive description: @@ -1352,42 +1376,42 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.5" vector_math: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: name: vm_service - sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" url: "https://pub.dev" source: hosted - version: "15.0.0" + version: "15.2.0" watcher: dependency: transitive description: name: watcher - sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a" + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.1" web: dependency: transitive description: @@ -1416,10 +1440,10 @@ packages: dependency: transitive description: name: win32 - sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e url: "https://pub.dev" source: hosted - version: "5.14.0" + version: "5.15.0" win32_registry: dependency: transitive description: @@ -1448,10 +1472,10 @@ packages: dependency: transitive description: name: xml - sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" url: "https://pub.dev" source: hosted - version: "6.5.0" + version: "6.6.1" yaml: dependency: transitive description: @@ -1461,5 +1485,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.8.0 <4.0.0" - flutter: ">=3.29.0" + dart: ">=3.11.0 <4.0.0" + flutter: ">=3.38.4" diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 93dbf81..21c3cff 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -11,6 +11,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + jni ) set(PLUGIN_BUNDLED_LIBRARIES)