From a30d194f9cd5f2dc34e322e95909b4533e43bef1 Mon Sep 17 00:00:00 2001 From: SurendarSuri30 Date: Fri, 17 Oct 2025 15:53:53 +0530 Subject: [PATCH] side bar profile issue --- android/app/build.gradle | 4 +- android/app/google-services.json | 55 +- android/app/src/main/AndroidManifest.xml | 3 +- ...ects=62d89bdaed190bcce8b2d4927903a80f-json | 1 + ios/Runner.xcodeproj/project.pbxproj | 20 +- ios/Runner/GoogleService-Info.plist | 10 +- lib/domain/use_cases/auth_use_case.dart | 4 +- lib/l10n/app_localizations.dart | 6 + lib/l10n/app_localizations_ar.dart | 3 + lib/l10n/app_localizations_en.dart | 3 + lib/l10n/intl_ar.arb | 1 + lib/l10n/intl_en.arb | 1 + .../auth_verification/registration.dart | 2320 +++++++++-------- .../Screens/charts/screens/chart_screen.dart | 3 +- lib/presentation/Screens/profilepage.dart | 36 +- .../routes/auth_routes/login_route.dart | 213 +- .../Drawer Items/edit_profile.dart | 36 +- .../routes/uae_pass/uaepass_pkce.dart | 14 + .../routes/uae_pass/uaepass_signin_page.dart | 74 + pubspec.lock | 32 +- pubspec.yaml | 11 +- 21 files changed, 1599 insertions(+), 1251 deletions(-) create mode 100644 android/build/ios/XCBuildData/PIFCache/workspace/WORKSPACE@v11_hash=(null)_subobjects=62d89bdaed190bcce8b2d4927903a80f-json create mode 100644 lib/presentation/routes/uae_pass/uaepass_pkce.dart create mode 100644 lib/presentation/routes/uae_pass/uaepass_signin_page.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 4602c6b5..b42f46eb 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) { def flutterVersionCode = localProperties.getProperty("flutter.versionCode") if (flutterVersionCode == null) { - flutterVersionCode = "69" + flutterVersionCode = "6" } def flutterVersionName = localProperties.getProperty("flutter.versionName") if (flutterVersionName == null) { - flutterVersionName = "1.0.68" + flutterVersionName = "1.0.6" } def keystorePropertiesFile = rootProject.file("key.properties") diff --git a/android/app/google-services.json b/android/app/google-services.json index d8d13fd2..2e8c2327 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,68 +1,29 @@ { "project_info": { - "project_number": "62132243005", - "project_id": "fcsc-a161c", - "storage_bucket": "fcsc-a161c.firebasestorage.app" + "project_number": "534109861443", + "project_id": "fcsc-uae-stats-9cb1e", + "storage_bucket": "fcsc-uae-stats-9cb1e.firebasestorage.app" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:62132243005:android:18b7ca94608afaeb7c7854", - "android_client_info": { - "package_name": "ae.gov.fcsc.frontend" - } - }, - "oauth_client": [ - { - "client_id": "62132243005-rnqthdakjs2ccs1ri7hnh79eh8t6hojl.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyB-QQbnq366f7rrKLVVFJKnSZgR9LcDWFI" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "62132243005-rnqthdakjs2ccs1ri7hnh79eh8t6hojl.apps.googleusercontent.com", - "client_type": 3 - } - ] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:62132243005:android:a50184ce50e0407d7c7854", + "mobilesdk_app_id": "1:534109861443:android:25d267f0c986b2042f46f6", "android_client_info": { "package_name": "ae.gov.fcsc.stats" } }, - "oauth_client": [ - { - "client_id": "62132243005-rnqthdakjs2ccs1ri7hnh79eh8t6hojl.apps.googleusercontent.com", - "client_type": 3 - } - ], + "oauth_client": [], "api_key": [ { - "current_key": "AIzaSyB-QQbnq366f7rrKLVVFJKnSZgR9LcDWFI" + "current_key": "AIzaSyDj1DrqD5WEiviIz3VtwCUCo-LuyFj32Bs" } ], "services": { "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "62132243005-rnqthdakjs2ccs1ri7hnh79eh8t6hojl.apps.googleusercontent.com", - "client_type": 3 - } - ] + "other_platform_oauth_client": [] } } } ], "configuration_version": "1" -} \ No newline at end of file +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7af982c5..c9ebcfc3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -37,8 +37,7 @@ - - + diff --git a/android/build/ios/XCBuildData/PIFCache/workspace/WORKSPACE@v11_hash=(null)_subobjects=62d89bdaed190bcce8b2d4927903a80f-json b/android/build/ios/XCBuildData/PIFCache/workspace/WORKSPACE@v11_hash=(null)_subobjects=62d89bdaed190bcce8b2d4927903a80f-json new file mode 100644 index 00000000..cfe5d7f8 --- /dev/null +++ b/android/build/ios/XCBuildData/PIFCache/workspace/WORKSPACE@v11_hash=(null)_subobjects=62d89bdaed190bcce8b2d4927903a80f-json @@ -0,0 +1 @@ +{"guid":"dc4b70c03e8043e50e38f2068887b1d4","name":"Pods","path":"/Users/venbateam/Documents/UAE_Stats/FCSC/frontend/ios/Pods/Pods.xcodeproj/project.xcworkspace","projects":["PROJECT@v11_mod=0b74ffacc71bdcf46ebf150515ee10c1_hash=bfdfe7dc352907fc980b868725387e98plugins=1OJSG6M1FOV3XYQCBH7Z29RZ0FPR9XDE1"]} \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a2218b00..5b86e877 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -337,14 +337,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -380,14 +376,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -506,7 +498,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_ASSET_PATHS = Runner/Assets.xcassets; DEVELOPMENT_TEAM = 9N5SRFUGK2; ENABLE_BITCODE = NO; @@ -517,7 +509,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.13; + MARKETING_VERSION = 1.0.15; PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -705,7 +697,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_ASSET_PATHS = Runner/Assets.xcassets; DEVELOPMENT_TEAM = 9N5SRFUGK2; ENABLE_BITCODE = NO; @@ -716,7 +708,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.13; + MARKETING_VERSION = 1.0.15; PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -742,7 +734,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_ASSET_PATHS = Runner/Assets.xcassets; DEVELOPMENT_TEAM = 9N5SRFUGK2; ENABLE_BITCODE = NO; @@ -753,7 +745,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.13; + MARKETING_VERSION = 1.0.15; PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist index cda5b568..65cdb2eb 100644 --- a/ios/Runner/GoogleService-Info.plist +++ b/ios/Runner/GoogleService-Info.plist @@ -3,17 +3,17 @@ API_KEY - AIzaSyCuGieAmgg217jhsx7foqpI-sOkAfEq5SU + AIzaSyBYWYHFIMuD5gEgbH9sEQk8kqqXX0zemJc GCM_SENDER_ID - 62132243005 + 534109861443 PLIST_VERSION 1 BUNDLE_ID ae.gov.fcsc.frontend.ios PROJECT_ID - fcsc-a161c + fcsc-uae-stats-9cb1e STORAGE_BUCKET - fcsc-a161c.firebasestorage.app + fcsc-uae-stats-9cb1e.firebasestorage.app IS_ADS_ENABLED IS_ANALYTICS_ENABLED @@ -25,6 +25,6 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:62132243005:ios:fcd5a574f5a796a47c7854 + 1:534109861443:ios:83bfecd0cfefa6d52f46f6 \ No newline at end of file diff --git a/lib/domain/use_cases/auth_use_case.dart b/lib/domain/use_cases/auth_use_case.dart index 319f0dc1..82d66885 100644 --- a/lib/domain/use_cases/auth_use_case.dart +++ b/lib/domain/use_cases/auth_use_case.dart @@ -71,9 +71,9 @@ class AuthUseCase extends _$AuthUseCase { } Future googleAndAppleAuthencation(token) async { - // print("loginTEST2"); + // print("loginTEST2 $token"); final session = await _repo.googleAndAppleAuthencation(token); - // print("loginTEST4"); + // print("loginTEST4 $session"); final localPrefs = await getIt.call().get(); if (localPrefs != null) { await getIt.call().syncPreferences( diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 8d43fb6c..45625799 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -446,6 +446,12 @@ abstract class AppLocalizations { /// **'Change Password'** String get change_password; + /// No description provided for @delete_account. + /// + /// In en, this message translates to: + /// **'Delete Account'** + String get delete_account; + /// No description provided for @sure_save_page. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index 5162da99..0b4714a8 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -186,6 +186,9 @@ class AppLocalizationsAr extends AppLocalizations { @override String get change_password => 'تغيير كلمة المرور'; + @override + String get delete_account => 'حذف الحساب'; + @override String get sure_save_page => ' هل أنت متأكد أنك ترغب في حفظ هذه الصفحة؟'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 3e044caf..36ee9295 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -186,6 +186,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get change_password => 'Change Password'; + @override + String get delete_account => 'Delete Account'; + @override String get sure_save_page => 'Are you sure you want to save this page? '; diff --git a/lib/l10n/intl_ar.arb b/lib/l10n/intl_ar.arb index 5776d62b..67442483 100644 --- a/lib/l10n/intl_ar.arb +++ b/lib/l10n/intl_ar.arb @@ -65,6 +65,7 @@ "cancel": "إلغاء", "confirm": "تأكيد", "change_password": "تغيير كلمة المرور", + "delete_account": "حذف الحساب", "sure_save_page": " هل أنت متأكد أنك ترغب في حفظ هذه الصفحة؟", "not_able_to_change": "بمجرد الحفظ، لن تتمكن من تعديل اسمك أو تاريخ ميلادك.", "save": "حفظ", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index a4aabcb2..261950f0 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -61,6 +61,7 @@ "cancel": "Cancel", "confirm": "Confirm", "change_password": "Change Password", + "delete_account": "Delete Account", "sure_save_page": "Are you sure you want to save this page? ", "not_able_to_change": "Once saved, you will not be able to change your ", "save": "Save", diff --git a/lib/presentation/Screens/auth_verification/registration.dart b/lib/presentation/Screens/auth_verification/registration.dart index a2db0574..f5e17320 100644 --- a/lib/presentation/Screens/auth_verification/registration.dart +++ b/lib/presentation/Screens/auth_verification/registration.dart @@ -231,7 +231,6 @@ class _RegisterScreenState extends ConsumerState { isRegistering = true; // Disable the button }); try { - // final adminToken = adminAuth.token; // print('adminTokenREgistration- ${adminToken}'); var mailID = _emailController.text; @@ -289,9 +288,9 @@ class _RegisterScreenState extends ConsumerState { 'Email Exists', 'البريد الإلكتروني موجود'), style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), content: Text( context.translate( @@ -299,9 +298,9 @@ class _RegisterScreenState extends ConsumerState { 'معرف البريد الإلكتروني موجود بالفعل. يرجى استخدام بريد إلكتروني آخر.'), style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), actions: [ TextButton( @@ -309,16 +308,16 @@ class _RegisterScreenState extends ConsumerState { Navigator.pop(context); setState(() { isRegistering = - false; // Re-enable the button after error + false; // Re-enable the button after error }); }, style: TextButton.styleFrom( backgroundColor: - Color(0xFFAA8E83), // Set background color + Color(0xFFAA8E83), // Set background color foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(10.0), // Set text color + BorderRadius.circular(10.0), // Set text color ), ), child: Text( @@ -407,7 +406,6 @@ class _RegisterScreenState extends ConsumerState { ); } - return PopScope( canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { @@ -429,7 +427,7 @@ class _RegisterScreenState extends ConsumerState { child: Consumer( builder: (context, ref, _) { final locale = - ref.watch(localeProvider); // Current locale + ref.watch(localeProvider); // Current locale return MyToggle( isOn: locale?.languageCode == 'en', knobTextWhenOn: 'ع', @@ -464,1120 +462,1226 @@ class _RegisterScreenState extends ConsumerState { Column(children: [ registrationSuccess ? Padding( - padding: const EdgeInsets.only( - top: 20.0, - left: 20.0, - right: 20.0, - bottom: 10.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: screenheight / 4), + padding: const EdgeInsets.only( + top: 20.0, + left: 20.0, + right: 20.0, + bottom: 10.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: screenheight / 4), - Container( - width: 60, - height: 60, - decoration: BoxDecoration( - color: Color(0xFFF9F9F9), - shape: BoxShape.circle, - boxShadow: [ - BoxShadow( - color: isDarkTheme - ? Colors.white - : Colors.black12, - blurRadius: isDarkTheme ? 0 : 6, - // offset: Offset(0, 2), + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Color(0xFFF9F9F9), + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: isDarkTheme + ? Colors.white + : Colors.black12, + blurRadius: isDarkTheme ? 0 : 6, + // offset: Offset(0, 2), + ), + ], + ), + child: Center( + child: SizedBox( + height: 35, + width: 35, + child: FittedBox( + fit: BoxFit.contain, + child: Image.asset( + MiscIconAssetPath.successMsg), + ), + ), + ), ), + // buildIconContainer( + // // Icons.check, Color(0xFFB68A34) + // // Color(0xFF7DAFBC) + // ), + SizedBox(height: 20), + Text( + context.translate( + 'Your registration is pending for verification.', + 'تسجيلك في انتظار التحقق.'), + textAlign: TextAlign.center, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500, + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF414042)), + ), + SizedBox(height: 10), + Text( + context.translate( + 'Kindly verify your mail to proceed further.', + 'يرجى التحقق من البريد الخاص بك للمضي قدما.'), + textAlign: TextAlign.center, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF898C81), + ), + ), + SizedBox(height: 10), + ElevatedButton( + onPressed: () => {context.go('/login')}, + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xFFB68A34), + + // isDarkTheme + // ? Color(0xFF24B4FB) + // : Color( + // 0xFFAA8E83), // Background color + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 12), // Border radius + ), + ), + child: Text( + context.translate('Go to Login', + 'اذهب إلى تسجيل الدخول'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Colors.white, // Text color + ), + ), + ), + SizedBox(height: screenheight / 5), + Center( + child: Container( + height: screenheight / 16, + // width: screenwidth / 2.5, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(isDarkTheme + ? BannerAssetPath.fcscLogoDark + : BannerAssetPath + .fcscLogoLight), // Background image asset + // fit: BoxFit.fill, + ), + ), + )) ], ), - child: Center( - child: SizedBox( - height: 35, - width: 35, - child: FittedBox( - fit: BoxFit.contain, - child: Image.asset( - MiscIconAssetPath.successMsg), - ), - ), - ), - ), - // buildIconContainer( - // // Icons.check, Color(0xFFB68A34) - // // Color(0xFF7DAFBC) - // ), - SizedBox(height: 20), - Text( - context.translate( - 'Your registration is pending for verification.', - 'تسجيلك في انتظار التحقق.'), - textAlign: TextAlign.center, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Color(0xFF414042)), - ), - SizedBox(height: 10), - Text( - context.translate( - 'Kindly verify your mail to proceed further.', - 'يرجى التحقق من البريد الخاص بك للمضي قدما.'), - textAlign: TextAlign.center, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 14, - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Color(0xFF898C81), - ), - ), - SizedBox(height: 10), - ElevatedButton( - onPressed: () => {context.go('/login')}, - style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFFB68A34), - - // isDarkTheme - // ? Color(0xFF24B4FB) - // : Color( - // 0xFFAA8E83), // Background color - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - 12), // Border radius - ), - ), - child: Text( - context.translate('Go to Login', - 'اذهب إلى تسجيل الدخول'), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Colors.white, // Text color - ), - ), - ), - SizedBox(height: screenheight / 5), - Center( - child: Container( - height: screenheight / 16, - // width: screenwidth / 2.5, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage(isDarkTheme - ? BannerAssetPath.fcscLogoDark - : BannerAssetPath - .fcscLogoLight), // Background image asset - // fit: BoxFit.fill, - ), - ), - )) - ], - ), - ) + ) : registrationFailed - ? Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: screenheight / 8), - buildIconContainer( - Icons.report, Colors.red), - SizedBox(height: 20), - Text( - context.translate( - 'Sorry ${_usernameController.text}!', - 'آسف ${_usernameController.text}!'), - textAlign: TextAlign.center, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Color(0xFF414042)), - ), - SizedBox(height: 10), - Text( - context.translate( - 'Your registration process failed. For further assistance, please contact support.', - 'فشلت عملية التسجيل الخاصة بك. لمزيد من المساعدة، يرجى الاتصال بالدعم.'), - textAlign: TextAlign.center, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 14, - color: isDarkTheme - ? Color(0xFFEEEEEE) - : Color(0xFF898C81), - ), - ), - SizedBox(height: 10), - ElevatedButton( - onPressed: () => { - setState(() { - registrationFailed = false; - registrationSuccess = false; - _usernameController.clear(); - _emailController.clear(); - _passwordController.clear(); - _confirmpasswordController.clear(); - isChecked = false; - }) - }, - child: Text( - context.translate( - 'Retry', 'أعد المحاولة'), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFFB68A34), - - // color: isDarkTheme - // ? Color(0xFF24B4FB) - // : Color(0xFFAA8E83), - ), - ), - ), - SizedBox(height: screenheight / 5), - Center( - child: Container( - height: screenheight / 16, - // width: screenwidth / 2.5, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage(isDarkTheme - ? BannerAssetPath.fcscLogoDark - : BannerAssetPath - .fcscLogoLight), // Background image asset - // fit: BoxFit.fill, - ), - ), - )) - ], - ), - ) - : Form( - key: _formKey, - child: SingleChildScrollView( - child: Column( - // mainAxisAlignment: - // MainAxisAlignment.center, - children: [ - SizedBox(height: screenheight / 60), - Text( - // 'Register', - AppLocalizations.of(context)! - .register_title, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 32, - fontWeight: FontWeight.w400, - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Color(0xFF000000), - ), - ), - SizedBox(height: 10), - Text( - AppLocalizations.of(context)! - .register_details, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: - context.translate(18.0, 14.0), - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Color(0xFF898C81), - fontWeight: FontWeight.w600, - ), - ), - - SizedBox(height: 15), - // Display this if registration is pending approval - Padding( - padding: const EdgeInsets.only( - top: 5.0, - bottom: 10, - left: 30, - right: 30), - child: TextFormField( - controller: _usernameController, - // focusNode: _focusNodes[0], - decoration: InputDecoration( - filled: true, - fillColor: isDarkTheme - ? const Color(0xFF000000) - : Colors.white, - errorStyle: TextStyle( - color: Color(0xFFD83731), - // color: isDarkTheme - // ? Color(0xFFFFA200) - // : Color(0xFFb22222), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ), - // hintText: _showHints[0] ? 'Username' : null, - hintText: _showHints[0] - ? AppLocalizations.of( - context)! - .register_name - : null, - prefixIconConstraints: - const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: - const EdgeInsetsDirectional - .only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.person, - fit: BoxFit.fitHeight, - height: 25, - width: 25, - ), - ), - - // prefixIcon: Icon( - // Icons.person, - // color: Color(0xFF90B0D5), - // - // ), - // border: OutlineInputBorder(), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color( - 0xFFB68A34), // ✅ border - width: 1), // Enabled border - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFB68A34), - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: 1), // Error border - ), - focusedErrorBorder: - OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: - 1), // Match the error color - ), - counterText: '', - hintStyle: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: const Color(0xFFC3C6CB), - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 14 - : 16, - ), - ), - validator: _validateUsername, - maxLength: - 40, // Set the maximum length to 20 characters - maxLengthEnforcement: - MaxLengthEnforcement.enforced, - ), - ), - SizedBox(height: 15), - Padding( - padding: const EdgeInsets.only( - top: 5.0, - bottom: 10, - left: 30, - right: 30), - child: TextFormField( - controller: _emailController, - // focusNode: _focusNodes[1], - decoration: InputDecoration( - filled: true, - fillColor: isDarkTheme - ? const Color(0xFF000000) - : Colors.white, - errorStyle: TextStyle( - color: Color(0xFFD83731), - // color: isDarkTheme - // ? Color(0xFFFFA200) - // : Color(0xFFb22222), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ), - // hintText: 'Enter your email', - hintText: _showHints[1] - ? AppLocalizations.of( - context)! - .enter_your_email - : null, - // _showHints[1] ? 'Enter your email' : null, - prefixIconConstraints: - const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: - const EdgeInsetsDirectional - .only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.vector, - fit: BoxFit.fitHeight, - height: 25, - width: 25, - ), - ), - - // border: OutlineInputBorder(), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFB68A34), - width: 1), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFB68A34), - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: 1), // Error border - ), - focusedErrorBorder: - OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: - 1), // Match the error color - ), - counterText: '', - hintStyle: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: const Color(0xFFC3C6CB), - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 14 - : 16, - ), - ), - validator: _validateEmail, - maxLength: 320, - maxLengthEnforcement: - MaxLengthEnforcement.enforced, - inputFormatters: [ - LengthLimitingTextInputFormatter( - 320), // Limit to 320 characters - ], - ), - ), - SizedBox(height: 15), - Padding( - padding: const EdgeInsets.only( - top: 5.0, - bottom: 10, - left: 30, - right: 30), - child: TextFormField( - controller: _passwordController, - // focusNode: _focusNodes[2], - obscureText: _obscurePassword, - decoration: InputDecoration( - filled: true, - fillColor: isDarkTheme - ? const Color(0xFF000000) - : Colors.white, - errorStyle: TextStyle( - color: Color(0xFFD83731), - // color: isDarkTheme - // ? Color(0xFFFFA200) - // : Color(0xFFb22222), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ), - hintText: _showHints[2] - ? AppLocalizations.of( - context)! - .enter_your_password - : null, - // _showHints[2] ? 'Enter your password' : null, - prefixIconConstraints: - const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: - const EdgeInsetsDirectional - .only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.lock, - fit: BoxFit.fitHeight, - height: 25, - width: 25, - ), - ), - - // prefixIcon: Icon( - // Icons.lock, - // color: Color(0xFF90B0D5), - // ), - suffixIcon: IconButton( - // icon: Icon( - // _obscurePassword - // ? Icons.visibility_off - // : Icons.visibility, - // color: Color(0xFF9EA2A9), - // ), - - icon: Image.asset( - _obscurePassword - ? MiscIconAssetPath - .visibilityOff - : MiscIconAssetPath - .visibleOn, - - color: Color( - 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. - width: 24, - height: 24, - ), - - onPressed: () { - setState(() { - _obscurePassword = - !_obscurePassword; - }); - }, - ), - // border: OutlineInputBorder(), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFB68A34), - width: 1), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFB68A34), - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: 1), // Error border - ), - focusedErrorBorder: - OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: - 1), // Match the error color - ), - - counterText: '', - hintStyle: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: const Color(0xFFC3C6CB), - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 14 - : 16, - ), - ), - validator: _validatePassword, - maxLength: 40, - maxLengthEnforcement: - MaxLengthEnforcement.enforced, - ), - ), - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.only( - top: 5.0, - bottom: 10, - left: 30, - right: 30), - child: TextFormField( - controller: - _confirmpasswordController, - // focusNode: _focusNodes[3], - obscureText: - _obscureConfirmPassword, - decoration: InputDecoration( - filled: true, - fillColor: isDarkTheme - ? const Color(0xFF000000) - : Colors.white, - errorStyle: TextStyle( - color: Color(0xFFD83731), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ), - hintText: _showHints[3] - ? AppLocalizations.of( - context)! - .register_Confirm_password - : null, - // _showHints[3] ? 'Confirm password' : null, - prefixIconConstraints: - const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: - const EdgeInsetsDirectional - .only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.lock, - fit: BoxFit.fitHeight, - height: 25, - width: 25, - ), - ), - - suffixIcon: IconButton( - icon: Image.asset( - _obscureConfirmPassword - ? MiscIconAssetPath - .visibilityOff - : MiscIconAssetPath - .visibleOn, - - color: Color( - 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. - width: 24, - height: 24, - ), - onPressed: () { - setState(() { - _obscureConfirmPassword = - !_obscureConfirmPassword; - }); - }, - ), - // border: OutlineInputBorder( - // borderSide: BorderSide(color: Colors.blue, width: 2), // Default border color - // ), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFB68A34), - width: 1), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFB68A34), - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: 1), // Error border - ), - focusedErrorBorder: - OutlineInputBorder( - borderRadius: - BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFD83731), - width: - 1), // Match the error color - ), - counterText: '', - hintStyle: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: const Color(0xFFC3C6CB), - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 14 - : 16, - ), - ), - validator: _validateConfirmPassword, - maxLength: 40, - maxLengthEnforcement: - MaxLengthEnforcement.enforced, - inputFormatters: [ - LengthLimitingTextInputFormatter( - 64), // Limit to 40 characters - ], - ), - ), - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.only( - top: 0, - bottom: 10, - left: 15.5, - right: 30), - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Checkbox( - value: isChecked, - onChanged: (value) { - setState(() { - isChecked = value ?? false; - showError = false; - }); - }, - side: BorderSide( - color: showError - ? Color(0xFFD83731) - : Color(0xFFB68A34), - width: 1, - ), - ), - Expanded( - child: Padding( - padding: - const EdgeInsets.only( - top: 0, - ), - child: Text.rich( - TextSpan( - text: AppLocalizations.of( - context, - )! - .agree, - // text: 'I agree to ', - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - ), - fontWeight: - FontWeight.w500, - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 12 - : 14, - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Color( - 0xFF898C81), // Change to your desired color + ? Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: screenheight / 8), + buildIconContainer( + Icons.report, Colors.red), + SizedBox(height: 20), + Text( + context.translate( + 'Sorry ${_usernameController.text}!', + 'آسف ${_usernameController.text}!'), + textAlign: TextAlign.center, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', ), - children: [ - TextSpan( - recognizer: - TapGestureRecognizer() - ..onTap = () => - context.push( - '/termsandconditions'), - text: AppLocalizations - .of(context)! - .terms_conditions, - // text: 'Terms & Conditions', - style: TextStyle( - fontFamily: context - .translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: - registerLocale - ?.languageCode == - 'ar' - ? 12 - : 14, - fontWeight: - FontWeight - .bold, - color: isDarkTheme - ? Color( - 0xFFB68A35) - : Color( - 0xFF985400), - // Makes the text bold - // decoration: - // TextDecoration.underline, - decorationColor: - Color( - 0xFF985400), - decorationThickness: - 1), - ), - TextSpan( - text: AppLocalizations - .of(context)! - .t_and, - style: TextStyle( - fontFamily: context - .translate( - 'Roboto', - 'NotoKufi', - ), - color: isDarkTheme - ? Color( - 0xFFFFFFFF) - : Color( - 0xFF898C81), + fontSize: 16, + fontWeight: FontWeight.w500, + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF414042)), + ), + SizedBox(height: 10), + Text( + context.translate( + 'Your registration process failed. For further assistance, please contact support.', + 'فشلت عملية التسجيل الخاصة بك. لمزيد من المساعدة، يرجى الاتصال بالدعم.'), + textAlign: TextAlign.center, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + color: isDarkTheme + ? Color(0xFFEEEEEE) + : Color(0xFF898C81), + ), + ), + SizedBox(height: 10), + ElevatedButton( + onPressed: () => { + setState(() { + registrationFailed = false; + registrationSuccess = false; + _usernameController.clear(); + _emailController.clear(); + _passwordController.clear(); + _confirmpasswordController.clear(); + isChecked = false; + }) + }, + child: Text( + context.translate( + 'Retry', 'أعد المحاولة'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Color(0xFFB68A34), + + // color: isDarkTheme + // ? Color(0xFF24B4FB) + // : Color(0xFFAA8E83), + ), + ), + ), + SizedBox(height: screenheight / 5), + Center( + child: Container( + height: screenheight / 16, + // width: screenwidth / 2.5, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(isDarkTheme + ? BannerAssetPath.fcscLogoDark + : BannerAssetPath + .fcscLogoLight), // Background image asset + // fit: BoxFit.fill, + ), + ), + )) + ], + ), + ) + : Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + // mainAxisAlignment: + // MainAxisAlignment.center, + children: [ + SizedBox(height: screenheight / 60), + Text( + // 'Register', + AppLocalizations.of(context)! + .register_title, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 32, + fontWeight: FontWeight.w400, + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF000000), + ), + ), + SizedBox(height: 10), + Text( + AppLocalizations.of(context)! + .register_details, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: + context.translate(18.0, 14.0), + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF898C81), + fontWeight: FontWeight.w600, + ), + ), + + SizedBox(height: 15), + // Display this if registration is pending approval + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: _usernameController, + // focusNode: _focusNodes[0], + decoration: InputDecoration( + filled: true, + fillColor: isDarkTheme + ? const Color(0xFF000000) + : Colors.white, + errorStyle: TextStyle( + color: Color(0xFFD83731), + // color: isDarkTheme + // ? Color(0xFFFFA200) + // : Color(0xFFb22222), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', ), ), - TextSpan( - recognizer: - TapGestureRecognizer() - ..onTap = () => - context.push( - '/privacy_policy'), - text: AppLocalizations - .of(context)! - .privacy_policy, - style: TextStyle( - fontFamily: context - .translate( - 'Roboto', - 'NotoKufi', - ), - fontWeight: - FontWeight - .bold, - fontSize: - registerLocale - ?.languageCode == - 'ar' - ? 12 - : 14, - color: isDarkTheme - ? Color( - 0xFFB68A35) - : Color( - 0xFF985400), - // decoration: - // TextDecoration.underline, - decorationColor: - Color( - 0xFF648CBA), - decorationThickness: - 1), + // hintText: _showHints[0] ? 'Username' : null, + hintText: _showHints[0] + ? AppLocalizations.of( + context)! + .register_name + : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), ), - TextSpan( - text: AppLocalizations - .of(context)! - .conditions, - style: TextStyle( - fontFamily: context - .translate( - 'Roboto', - 'NotoKufi', + prefixIcon: Padding( + padding: + const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.person, + fit: BoxFit.fitHeight, + height: 25, + width: 25, + ), + ), + + // prefixIcon: Icon( + // Icons.person, + // color: Color(0xFF90B0D5), + // + // ), + // border: OutlineInputBorder(), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color( + 0xFFB68A34), // ✅ border + width: 1), // Enabled border + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFB68A34), + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: + 1), // Match the error color + ), + counterText: '', + hintStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: const Color(0xFFC3C6CB), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validateUsername, + maxLength: + 40, // Set the maximum length to 20 characters + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + ), + ), + SizedBox(height: 15), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: _emailController, + // focusNode: _focusNodes[1], + decoration: InputDecoration( + filled: true, + fillColor: isDarkTheme + ? const Color(0xFF000000) + : Colors.white, + errorStyle: TextStyle( + color: Color(0xFFD83731), + // color: isDarkTheme + // ? Color(0xFFFFA200) + // : Color(0xFFb22222), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + // hintText: 'Enter your email', + hintText: _showHints[1] + ? AppLocalizations.of( + context)! + .enter_your_email + : null, + // _showHints[1] ? 'Enter your email' : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), + ), + prefixIcon: Padding( + padding: + const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.vector, + fit: BoxFit.fitHeight, + height: 25, + width: 25, + ), + ), + + // border: OutlineInputBorder(), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFB68A34), + width: 1), + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFB68A34), + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: + 1), // Match the error color + ), + counterText: '', + hintStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: const Color(0xFFC3C6CB), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validateEmail, + maxLength: 320, + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + inputFormatters: [ + LengthLimitingTextInputFormatter( + 320), // Limit to 320 characters + ], + ), + ), + SizedBox(height: 15), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: _passwordController, + // focusNode: _focusNodes[2], + obscureText: _obscurePassword, + decoration: InputDecoration( + filled: true, + fillColor: isDarkTheme + ? const Color(0xFF000000) + : Colors.white, + errorStyle: TextStyle( + color: Color(0xFFD83731), + // color: isDarkTheme + // ? Color(0xFFFFA200) + // : Color(0xFFb22222), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + hintText: _showHints[2] + ? AppLocalizations.of( + context)! + .enter_your_password + : null, + // _showHints[2] ? 'Enter your password' : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), + ), + prefixIcon: Padding( + padding: + const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.lock, + fit: BoxFit.fitHeight, + height: 25, + width: 25, + ), + ), + + // prefixIcon: Icon( + // Icons.lock, + // color: Color(0xFF90B0D5), + // ), + suffixIcon: IconButton( + // icon: Icon( + // _obscurePassword + // ? Icons.visibility_off + // : Icons.visibility, + // color: Color(0xFF9EA2A9), + // ), + + icon: Image.asset( + _obscurePassword + ? MiscIconAssetPath + .visibilityOff + : MiscIconAssetPath + .visibleOn, + + color: Color( + 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. + width: 24, + height: 24, + ), + + onPressed: () { + setState(() { + _obscurePassword = + !_obscurePassword; + }); + }, + ), + // border: OutlineInputBorder(), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFB68A34), + width: 1), + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFB68A34), + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: + 1), // Match the error color + ), + + counterText: '', + hintStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: const Color(0xFFC3C6CB), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validatePassword, + maxLength: 40, + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + ), + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: + _confirmpasswordController, + // focusNode: _focusNodes[3], + obscureText: + _obscureConfirmPassword, + decoration: InputDecoration( + filled: true, + fillColor: isDarkTheme + ? const Color(0xFF000000) + : Colors.white, + errorStyle: TextStyle( + color: Color(0xFFD83731), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + hintText: _showHints[3] + ? AppLocalizations.of( + context)! + .register_Confirm_password + : null, + // _showHints[3] ? 'Confirm password' : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), + ), + prefixIcon: Padding( + padding: + const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.lock, + fit: BoxFit.fitHeight, + height: 25, + width: 25, + ), + ), + + suffixIcon: IconButton( + icon: Image.asset( + _obscureConfirmPassword + ? MiscIconAssetPath + .visibilityOff + : MiscIconAssetPath + .visibleOn, + + color: Color( + 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. + width: 24, + height: 24, + ), + onPressed: () { + setState(() { + _obscureConfirmPassword = + !_obscureConfirmPassword; + }); + }, + ), + // border: OutlineInputBorder( + // borderSide: BorderSide(color: Colors.blue, width: 2), // Default border color + // ), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFB68A34), + width: 1), + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFB68A34), + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFD83731), + width: + 1), // Match the error color + ), + counterText: '', + hintStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: const Color(0xFFC3C6CB), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validateConfirmPassword, + maxLength: 40, + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + inputFormatters: [ + LengthLimitingTextInputFormatter( + 64), // Limit to 40 characters + ], + ), + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only( + top: 0, + bottom: 0, + left: 15.5, + right: 30), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Checkbox( + value: isChecked, + onChanged: (value) { + setState(() { + isChecked = value ?? false; + showError = false; + }); + }, + side: BorderSide( + color: showError + ? Color(0xFFD83731) + : Color(0xFFB68A34), + width: 1, + ), + ), + Expanded( + child: Padding( + padding: + const EdgeInsets.only( + top: 0, + ), + child: Text.rich( + TextSpan( + text: AppLocalizations.of( + context, + )! + .agree, + // text: 'I agree to ', + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + fontWeight: + FontWeight.w500, + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 12 + : 14, + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color( + 0xFF898C81), // Change to your desired color + ), + children: [ + TextSpan( + recognizer: + TapGestureRecognizer() + ..onTap = () => + context.push( + '/termsandconditions'), + text: AppLocalizations + .of(context)! + .terms_conditions, + // text: 'Terms & Conditions', + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: + registerLocale + ?.languageCode == + 'ar' + ? 12 + : 14, + fontWeight: + FontWeight + .bold, + color: isDarkTheme + ? Color( + 0xFFB68A35) + : Color( + 0xFF985400), + // Makes the text bold + // decoration: + // TextDecoration.underline, + decorationColor: + Color( + 0xFF985400), + decorationThickness: + 1), + ), + TextSpan( + text: AppLocalizations + .of(context)! + .t_and, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme + ? Color( + 0xFFFFFFFF) + : Color( + 0xFF898C81), + ), + ), + TextSpan( + recognizer: + TapGestureRecognizer() + ..onTap = () => + context.push( + '/privacy_policy'), + text: AppLocalizations + .of(context)! + .privacy_policy, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + fontWeight: + FontWeight + .bold, + fontSize: + registerLocale + ?.languageCode == + 'ar' + ? 12 + : 14, + color: isDarkTheme + ? Color( + 0xFFB68A35) + : Color( + 0xFF985400), + // decoration: + // TextDecoration.underline, + decorationColor: + Color( + 0xFF648CBA), + decorationThickness: + 1), + ), + TextSpan( + text: AppLocalizations + .of(context)! + .conditions, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + fontWeight: + FontWeight.w500, + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 12 + : 14, + color: isDarkTheme + ? Color( + 0xFFFFFFFF) + : Color( + 0xFF898C81), // Change to your desired color + ), + ), + ], + ), ), - fontWeight: - FontWeight.w500, - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 12 - : 14, - color: isDarkTheme - ? Color( - 0xFFFFFFFF) - : Color( - 0xFF898C81), // Change to your desired color ), ), ], ), ), - ), - ), - ], - ), - ), - if (showError) - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only( - left: registerLocale - ?.languageCode == - 'ar' - ? 0 - : 40.0, - right: registerLocale - ?.languageCode == - 'ar' - ? 45 - : 0.0, - ), - child: Text( - context.translate( - 'Required', 'مطلوب'), - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', + if (showError) + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + left: registerLocale + ?.languageCode == + 'ar' + ? 0 + : 40.0, + right: registerLocale + ?.languageCode == + 'ar' + ? 45 + : 0.0, + ), + child: Text( + context.translate( + 'Required', 'مطلوب'), + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Color(0xFFD83731), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 12 + : 12, + ), + ), + ), + ], ), - color: Color(0xFFD83731), - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 12 - : 12, - ), - ), - ), - ], - ), - SizedBox(height: 20), - Padding( - padding: const EdgeInsets.only( - top: 5.0, - bottom: 10, - left: 30, - right: 30), - child: SizedBox( - width: screenwidth / 1, - child: ElevatedButton( - onPressed: isRegistering - ? null - : _registerUser, - style: ElevatedButton.styleFrom( - backgroundColor: Color( - 0xFFB68A34), // Brownish color for Register - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10), - ), - padding: EdgeInsets.symmetric(vertical: 16.5), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - // "Register", - AppLocalizations.of( - context)! - .register_title, - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', + SizedBox(height: 20), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 0, + left: 30, + right: 30), + child: SizedBox( + width: screenwidth / 1, + child: ElevatedButton( + onPressed: isRegistering + ? null + : _registerUser, + style: ElevatedButton.styleFrom( + backgroundColor: Color( + 0xFFB68A34), // Brownish color for Register + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(10), + ), + padding: EdgeInsets.symmetric( + vertical: 16.5), ), - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 14 - : 16, - color: Colors.white), - ), - SizedBox(width: 8), - Icon( - Icons - .chevron_right_outlined, - color: Colors - .white, // Set your desired color here - ) - ], - ), - ), - ), - ), - SizedBox(height: 10), - Text( - AppLocalizations.of(context)! - .account_confirmation, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontWeight: FontWeight.w500, - fontSize: - registerLocale?.languageCode == - 'ar' - ? 12 - : 14, - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Color(0xFF898C81), - ), - ), - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.only( - top: 5.0, - bottom: 10, - left: 30, - right: 30), - child: SizedBox( - width: screenwidth / 1, - child: ElevatedButton( - onPressed: () { - context.pop(); - }, - style: ElevatedButton.styleFrom( - backgroundColor: Color( - 0xFFB68A34), // Blueish color for Login - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10), - ), - padding: EdgeInsets.symmetric(vertical: 16.5), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - AppLocalizations.of( - context)! - .login_title, - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + // "Register", + AppLocalizations.of( + context)! + .register_title, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 14 + : 16, + color: Colors.white), + ), + SizedBox(width: 8), + Icon( + Icons + .chevron_right_outlined, + color: Colors + .white, // Set your desired color here + ) + ], ), - fontSize: registerLocale - ?.languageCode == - 'ar' - ? 14 - : 16, - color: Colors.white), + ), + ), ), - SizedBox(width: 8), - Icon( - Icons - .chevron_right_outlined, - color: Colors - .white, // Set your desired color here - ) - ], - ), - ), - ), - ), - // Spacer(), + // SizedBox(height: 10), + // + // Padding( + // padding: const EdgeInsets.only( + // top: 5.0, + // bottom: 0, + // left: 30, + // right: 30), + // child: SizedBox( + // width: double.infinity, + // child: Row( + // children: [ + // // Left line + // Expanded( + // child: Divider( + // color: isDarkTheme + // ? Colors.white + // : Colors.grey.shade400, + // thickness: 1, + // endIndent: 10, + // ), + // ), + // + // // Center text + // Text( + // 'OR', + // style: TextStyle( + // color: isDarkTheme + // ? Colors.white + // : Color(0x33000000), + // fontWeight: FontWeight.w600, + // fontSize: 16, + // ), + // ), + // + // // Right line + // Expanded( + // child: Divider( + // color: isDarkTheme + // ? Colors.white + // : Colors.grey.shade400, + // thickness: 1, + // indent: 10, + // ), + // ), + // ], + // ), + // ), + // ), + // SizedBox(height: 10), + // Padding( + // padding: const EdgeInsets.only( + // top: 5.0, + // bottom: 0, + // left: 60, + // right: 60), + // child: SizedBox( + // width: double.infinity, + // child: OutlinedButton( + // onPressed: () async {}, + // style: OutlinedButton.styleFrom( + // side: const BorderSide( + // color: Color(0xFF000000)), + // shape: RoundedRectangleBorder( + // borderRadius: + // BorderRadius.circular(8), + // ), + // padding: + // const EdgeInsets.symmetric( + // vertical: 16.5), + // backgroundColor: Colors.white, + // foregroundColor: Colors.black, + // textStyle: TextStyle( + // fontFamily: context.translate( + // 'Roboto', 'NotoKufi'), + // fontSize: 16, + // fontWeight: FontWeight.w500, + // ), + // ), + // child: Row( + // mainAxisAlignment: + // MainAxisAlignment.center, + // children: [ + // Image.asset( + // MiscIconAssetPath + // .signInWithUAEPass, // replace with your Google icon asset + // height: 20, + // ), + // const SizedBox(width: 10), + // Text( + // 'Sign in with UAE PASS', + // textAlign: TextAlign.center, + // style: TextStyle( + // color: Color(0xFF000000), + // fontWeight: + // FontWeight.w600, + // ), + // ), + // ], + // ), + // ), + // ), + // ), - SizedBox( - height: 10, - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 70.0), - // child: Container( - // height: screenheight / 16, - // width: screenwidth / 3, - // decoration: BoxDecoration( - // image: DecorationImage( - // image: AssetImage( - // "assets/splash_screen/logo.png"), // Background image asset - // fit: BoxFit.fill, - // ), - // ), - // ) - child: fcscBanner, - ), - // SizedBox( - // height: 5, - // ), - ], - ), - ), - ), + SizedBox(height: 20), + Text( + AppLocalizations.of(context)! + .account_confirmation, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontWeight: FontWeight.w500, + fontSize: + registerLocale?.languageCode == + 'ar' + ? 12 + : 14, + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Color(0xFF898C81), + ), + ), + SizedBox(height: 5), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 0, + left: 30, + right: 30), + child: SizedBox( + width: screenwidth / 1, + child: ElevatedButton( + onPressed: () { + context.pop(); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Color( + 0xFFB68A34), // Blueish color for Login + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(10), + ), + padding: EdgeInsets.symmetric( + vertical: 16.5), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + AppLocalizations.of( + context)! + .login_title, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 14 + : 16, + color: Colors.white), + ), + SizedBox(width: 8), + Icon( + Icons + .chevron_right_outlined, + color: Colors + .white, // Set your desired color here + ) + ], + ), + ), + ), + ), + // Spacer(), + + SizedBox( + height: 15, + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 70.0), + // child: Container( + // height: screenheight / 16, + // width: screenwidth / 3, + // decoration: BoxDecoration( + // image: DecorationImage( + // image: AssetImage( + // "assets/splash_screen/logo.png"), // Background image asset + // fit: BoxFit.fill, + // ), + // ), + // ) + child: fcscBanner, + ), + // SizedBox( + // height: 5, + // ), + ], + ), + ), + ), ]), // Container( // height: MediaQuery.of(context).size.height / 1.2, @@ -1598,7 +1702,7 @@ class _RegisterScreenState extends ConsumerState { child: LinearProgressIndicator( minHeight: 5, // Adjust thickness backgroundColor: - Colors.grey[100], // Optional: Background color + Colors.grey[100], // Optional: Background color valueColor: AlwaysStoppedAnimation( Color(0xFFAA8E83)), // Loader color ), @@ -1610,4 +1714,4 @@ class _RegisterScreenState extends ConsumerState { )), ); } -} \ No newline at end of file +} diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index de9a85a1..35f0165f 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -2294,7 +2294,8 @@ class _ChartScreen1State extends ConsumerState { try { final String currentRoute = GoRouterState.of(context).uri.toString(); - final String baseAppLink = 'https://fcscapp.onelink.me'; + // final String baseAppLink = 'https://fcscapp.onelink.me'; + final String baseAppLink = 'https://fcscstats.onelink.me'; final String shareLink = '$baseAppLink$currentRoute'; final String shareText = 'Check this out!\n\n$shareLink'; print('Generated Share Link: $shareLink'); diff --git a/lib/presentation/Screens/profilepage.dart b/lib/presentation/Screens/profilepage.dart index 5e61cb8f..1c14d07f 100644 --- a/lib/presentation/Screens/profilepage.dart +++ b/lib/presentation/Screens/profilepage.dart @@ -27,6 +27,7 @@ import 'package:uae_stat/presentation/components/indicators/locale_provider.dart import 'package:uae_stat/presentation/components/my_toggle.dart'; import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart'; +import 'package:url_launcher/url_launcher.dart'; class ProfileScreen extends ConsumerStatefulWidget { final String userId; // Add this field to hold the user ID @@ -1511,7 +1512,40 @@ class _ProfileScreenState extends ConsumerState { ), ], ), - ) + ), + SizedBox(height: 20), + Center( + child: GestureDetector( + onTap: () async { + final Uri url = Uri.parse('https://pocket.fcsc.gov.ae/accountdeletion/index.html'); + if (await canLaunchUrl(url)) { + await launchUrl( + url, + mode: LaunchMode.externalApplication, // opens in browser + ); + } else { + throw 'Could not launch $url'; + } + }, + child: Text( + AppLocalizations.of(context)!.delete_account, + style: TextStyle( + // color: Color(0xFF648CBA), + color: Color(0xFFB68A34), + // color: isDarkTheme + // ? Color(0xFF9EB3E4) + // : Color(0xFF985400), + fontSize: 14, + fontWeight: FontWeight.w700, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + // decoration: TextDecoration.underline), + ), + ), + ), + ), ], ), ), diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index 61a0da8a..e54713c3 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -1,13 +1,16 @@ import 'dart:convert'; +import 'dart:io'; import 'package:android_intent_plus/android_intent.dart'; import 'package:android_intent_plus/flag.dart'; import 'package:external_repos/external_repos.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:flutter_uae_pass/flutter_uae_pass.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:jwt_decoder/jwt_decoder.dart'; @@ -35,6 +38,7 @@ import 'package:uae_stat/presentation/components/space.dart'; import 'package:uae_stat/presentation/components/themed_text_field.dart'; import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home/home_route.dart'; import 'package:http/http.dart' as http; +import 'package:uae_stat/presentation/routes/uae_pass/uaepass_signin_page.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../Screens/auth_verification/registration.dart'; import 'package:pocketbase/pocketbase.dart'; @@ -59,6 +63,10 @@ class LoginRoute extends HookConsumerWidget { final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; // final FirebaseAuth _auth = FirebaseAuth.instance; static final formKey = GlobalKey(); + String? authCode; + String? accessToken; + ProfileData? profileData; + final _uaePass = UaePass(); Future profileStatus(String userId, WidgetRef ref) async { try { @@ -138,55 +146,80 @@ class LoginRoute extends HookConsumerWidget { // } Future getDeviceToken( - BuildContext context, String userId, WidgetRef ref) async { + BuildContext context, String userId, WidgetRef ref,authtoken) async { try { // await _firebaseMessaging.requestPermission(); - print("FCM Token Entry"); - String? token = await FirebaseMessaging.instance.getToken(); - print("FCM Token: $token"); + // print("FCM Token Entry"); + // String? token = await FirebaseMessaging.instance.getToken(); + // print("FCM Token: $token"); - if (token != null) { - await updateDeviceToken(userId, token, ref); + if (Platform.isIOS || Platform.isMacOS) { + // Get APNS token + String? token = await _firebaseMessaging.getAPNSToken(); + print('📱 APNS Token (iOS): $token'); - // Automatically copy to clipboard - // Clipboard.setData(ClipboardData(text: token)); + // Retry if null + if (token == null) { + await Future.delayed(const Duration(seconds: 3)); + token = await _firebaseMessaging.getAPNSToken(); + print('🔁 Retried APNS Token: $token'); + } - // Show token in Alert Dialog - // if (context.mounted) { - // showDialog( - // context: context, - // builder: (context) { - // return AlertDialog( - // title: Text("FCM Token"), - // content: Column( - // mainAxisSize: MainAxisSize.min, - // children: [ - // SelectableText(token), // Allows manual selection - // SizedBox(height: 10), - // Text( - // "Token copied to clipboard ✅", - // style: TextStyle(color: Colors.green), - // ), - // ], - // ), - // actions: [ - // TextButton( - // onPressed: () => Navigator.pop(context), - // child: Text("OK"), - // ), - // ], - // ); - // }, - // ); - // } + if (token != null) { + await updateDeviceToken(userId, token, ref,authtoken); + } + } else if (Platform.isAndroid) { + // Get FCM token + String? fcmToken = await _firebaseMessaging.getToken(); + print('🔥 FCM Token (Android): $fcmToken'); + + if (fcmToken != null) { + await updateDeviceToken(userId, fcmToken, ref,authtoken); + } } + + // if (token != null) { + // await updateDeviceToken(userId, token, ref,authtoken); + // + // // Automatically copy to clipboard + // // Clipboard.setData(ClipboardData(text: token)); + // + // // Show token in Alert Dialog + // // if (context.mounted) { + // // showDialog( + // // context: context, + // // builder: (context) { + // // return AlertDialog( + // // title: Text("FCM Token"), + // // content: Column( + // // mainAxisSize: MainAxisSize.min, + // // children: [ + // // SelectableText(token), // Allows manual selection + // // SizedBox(height: 10), + // // Text( + // // "Token copied to clipboard ✅", + // // style: TextStyle(color: Colors.green), + // // ), + // // ], + // // ), + // // actions: [ + // // TextButton( + // // onPressed: () => Navigator.pop(context), + // // child: Text("OK"), + // // ), + // // ], + // // ); + // // }, + // // ); + // // } + // } } catch (e) { print("Error getting FCM Token: $e"); } } Future updateDeviceToken( - String userId, String token, WidgetRef ref) async { + String userId, String token, WidgetRef ref,authtoken) async { final url = "${pb.baseUrl}api/collections/users/records/$userId"; try { @@ -213,7 +246,7 @@ class LoginRoute extends HookConsumerWidget { Uri.parse(url), headers: { 'Content-Type': 'application/json', // Add this - 'Authorization': PocketBaseService.authStore.token, // Correct way to send auth token + 'Authorization': 'Bearer $authtoken', // Correct way to send auth token }, body: jsonEncode({ "device_token": token, @@ -347,6 +380,24 @@ class LoginRoute extends HookConsumerWidget { } } + Future login() async { + authCode = null; + accessToken = null; + profileData = null; + try { + authCode = await _uaePass.signIn(); + print('authCode $authCode'); + accessToken = await _uaePass.getAccessToken(authCode ?? ""); + print('accessToken $accessToken'); + profileData = await _uaePass.getProfile(accessToken ?? ""); + print('profileData $profileData'); + } catch (e) { + if (kDebugMode) { + print(e.toString()); + } + } + } + Future initializeTheme( BuildContext context, WidgetRef ref, String userId) async { final themeService = ThemeBaseService(); @@ -362,8 +413,9 @@ class LoginRoute extends HookConsumerWidget { Future oAuthGoogleAndAppleLogin( BuildContext context, WidgetRef ref, platform) async { - print(platform); + print('platform $platform'); try { + print('platform $platform'); final authData = await pb.collection('users').authWithOAuth2(platform, (url) async { await launchUrl(url); @@ -385,7 +437,7 @@ class LoginRoute extends HookConsumerWidget { // } // }, // ); - print(authData); + print('authData $authData'); // ✅ Check if authData is valid if (authData.token.isNotEmpty && authData.record != null) { print("✅ Login Successful"); @@ -438,7 +490,7 @@ class LoginRoute extends HookConsumerWidget { await loginCountApi(userId!); await updateOAuthUserDetails(userId!, metaDetails, ref,token); // await saveUserId(userId!, loginCount); - // await getDeviceToken(context, userId); + await getDeviceToken(context, userId,ref,token); await initializeTheme(context, ref, userId); // final se = _sessionEntityFromPocketbaseRecord(authData); @@ -649,6 +701,13 @@ print('User response $response'); @override Widget build(BuildContext context, WidgetRef ref) { + + + useEffect(() { + _uaePass.setUpSandbox(); // equivalent to initState() + return null; // no cleanup needed + }, const []); + ref.listen>(connectivityProvider, (previous, hasInternet) { if (hasInternet.value == false) { context.push('/internetcheck'); @@ -1014,7 +1073,7 @@ print('User response $response'); } await saveUserId(userId, loginCount); - await getDeviceToken(context, userId, ref); + await getDeviceToken(context, userId, ref, PocketBaseService.authStore.token); await initializeTheme(context, ref, userId); } try { @@ -1331,6 +1390,40 @@ print('User response $response'); // ), // ), // ); + final orText = SizedBox( + width: double.infinity, + child: Row( + children: [ + // Left line + Expanded( + child: Divider( + color: isDarkTheme ? Colors.white : Colors.grey.shade400, + thickness: 1, + endIndent: 10, + ), + ), + + // Center text + Text( + 'OR', + style: TextStyle( + color: isDarkTheme ? Colors.white : Color(0x33000000), + fontWeight: FontWeight.w600, + fontSize: 16, + ), + ), + + // Right line + Expanded( + child: Divider( + color: isDarkTheme ? Colors.white : Colors.grey.shade400, + thickness: 1, + indent: 10, + ), + ), + ], + ), + ); final signInWithGoogleBtn = SizedBox( width: double.infinity, child: OutlinedButton( @@ -1413,10 +1506,21 @@ print('User response $response'); ), ), ); - final signInWithUAEPassBtn = SizedBox( + final signInWithUAEPassBtn = Padding( + padding: const EdgeInsets.only( + left: 60, + right: 60), + child: SizedBox( width: double.infinity, child: OutlinedButton( - onPressed: () async {}, + onPressed: () async { + // oAuthGoogleAndAppleLogin(context, ref, 'uaepass'); + login(); + // Navigator.push( + // context, + // MaterialPageRoute(builder: (context) => const UAEPassSignInPage()), + // ); + }, style: OutlinedButton.styleFrom( side: const BorderSide(color: Color(0xFF000000)), shape: RoundedRectangleBorder( @@ -1451,7 +1555,7 @@ print('User response $response'); ], ), ), - ); + )); final fcscBanner = Padding( padding: const EdgeInsets.symmetric(horizontal: 50), child: Image.asset( @@ -1507,13 +1611,18 @@ print('User response $response'); 25.verticalSpace, dontHaveAnAccountRegisterBtn, // continueAsGuestBtn, - 25.verticalSpace, - signInWithGoogleBtn, - 15.verticalSpace, - signInWithAppleBtn, - 15.verticalSpace, - signInWithUAEPassBtn, - 25.verticalSpace, + // 15.verticalSpace, + // orText, + // 15.verticalSpace, + // signInWithUAEPassBtn, + // 15.verticalSpace, + // orText, + // 15.verticalSpace, + // signInWithGoogleBtn, + // 15.verticalSpace, + // signInWithAppleBtn, + // 30.verticalSpace, + 120.verticalSpace, fcscBanner, ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart index 02702845..818151d0 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -28,6 +28,7 @@ import 'package:uae_stat/presentation/components/indicators/locale_provider.dart import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/l10n/app_localizations.dart'; +import 'package:url_launcher/url_launcher.dart'; class EditProfile extends ConsumerStatefulWidget { const EditProfile({super.key}); @@ -1514,7 +1515,40 @@ class _EditProfileState extends ConsumerState { ), ], ), - ) + ), + SizedBox(height: 20), + Center( + child: GestureDetector( + onTap: () async { + final Uri url = Uri.parse('https://pocket.fcsc.gov.ae/accountdeletion/index.html'); + if (await canLaunchUrl(url)) { + await launchUrl( + url, + mode: LaunchMode.externalApplication, // opens in browser + ); + } else { + throw 'Could not launch $url'; + } + }, + child: Text( + AppLocalizations.of(context)!.delete_account, + style: TextStyle( + // color: Color(0xFF648CBA), + color: Color(0xFFB68A34), + // color: isDarkTheme + // ? Color(0xFF9EB3E4) + // : Color(0xFF985400), + fontSize: 14, + fontWeight: FontWeight.w700, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + // decoration: TextDecoration.underline), + ), + ), + ), + ), ], ), ), diff --git a/lib/presentation/routes/uae_pass/uaepass_pkce.dart b/lib/presentation/routes/uae_pass/uaepass_pkce.dart new file mode 100644 index 00000000..5a39e669 --- /dev/null +++ b/lib/presentation/routes/uae_pass/uaepass_pkce.dart @@ -0,0 +1,14 @@ +// import 'dart:convert'; +// import 'dart:math'; +// import 'package:crypto/crypto.dart'; +// +// String randomString(int length) { +// final r = Random.secure(); +// final bytes = List.generate(length, (_) => r.nextInt(256)); +// return base64UrlEncode(bytes).replaceAll('=', ''); +// } +// +// String codeChallengeFromVerifier(String verifier) { +// final h = sha256.convert(utf8.encode(verifier)); +// return base64UrlEncode(h.bytes).replaceAll('=', ''); +// } diff --git a/lib/presentation/routes/uae_pass/uaepass_signin_page.dart b/lib/presentation/routes/uae_pass/uaepass_signin_page.dart new file mode 100644 index 00000000..70439a70 --- /dev/null +++ b/lib/presentation/routes/uae_pass/uaepass_signin_page.dart @@ -0,0 +1,74 @@ +// import 'package:flutter/material.dart'; +// import 'package:webview_flutter/webview_flutter.dart'; +// import 'package:webview_flutter_android/webview_flutter_android.dart'; +// import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; +// +// class UAEPassSignInPage extends StatefulWidget { +// const UAEPassSignInPage({Key? key}) : super(key: key); +// +// @override +// State createState() => _UAEPassSignInPageState(); +// } +// +// class _UAEPassSignInPageState extends State { +// late final WebViewController _controller; +// +// @override +// void initState() { +// super.initState(); +// +// late PlatformWebViewControllerCreationParams params; +// +// if (WebViewPlatform.instance is WebKitWebViewPlatform) { +// params = WebKitWebViewControllerCreationParams( +// allowsInlineMediaPlayback: true, +// mediaTypesRequiringUserAction: const {}, +// ); +// } else { +// params = const PlatformWebViewControllerCreationParams(); +// } +// +// final controller = WebViewController.fromPlatformCreationParams(params); +// +// controller +// ..setJavaScriptMode(JavaScriptMode.unrestricted) +// ..setNavigationDelegate( +// NavigationDelegate( +// onPageStarted: (String url) { +// debugPrint('Started loading: $url'); +// }, +// onPageFinished: (String url) { +// debugPrint('Finished loading: $url'); +// }, +// onNavigationRequest: (NavigationRequest request) { +// // Handle UAE PASS redirect URLs here +// if (request.url.contains('your-redirect-uri')) { +// debugPrint('Redirect detected: ${request.url}'); +// // You can now extract the token from the URL +// return NavigationDecision.prevent; +// } +// return NavigationDecision.navigate; +// }, +// ), +// ) +// ..loadRequest(Uri.parse('https://stg-id.uaepass.ae/idshub/authorize')); +// +// if (controller.platform is AndroidWebViewController) { +// AndroidWebViewController.enableDebugging(true); +// (controller.platform as AndroidWebViewController) +// .setMediaPlaybackRequiresUserGesture(false); +// } +// +// _controller = controller; +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: const Text('Sign in with UAE PASS'), +// ), +// body: WebViewWidget(controller: _controller), +// ); +// } +// } diff --git a/pubspec.lock b/pubspec.lock index 9216ddcd..4fa21de1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -751,6 +751,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_uae_pass: + dependency: "direct main" + description: + name: flutter_uae_pass + sha256: c0e5de77e01b8f26cddcad5e00b530c680bff280acf3b4851d18e974bcfdbdf2 + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter_web_auth_2: dependency: "direct main" description: @@ -1859,34 +1867,34 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec" + sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba url: "https://pub.dev" source: hosted - version: "4.10.0" + version: "4.13.0" webview_flutter_android: - dependency: transitive + dependency: "direct main" description: name: webview_flutter_android - sha256: "631093a7fbd93e9690ac61d8c8f3e857efbc189fc33f712b9ad6c01a623517ef" + sha256: e5201c620eb2637dca88a756961fae4a7191bb30b4f2271e08b746405ffdf3fd url: "https://pub.dev" source: hosted - version: "4.3.3" + version: "4.10.5" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d + sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.14.0" webview_flutter_wkwebview: - dependency: transitive + dependency: "direct main" description: name: webview_flutter_wkwebview - sha256: c49a98510080378b1525132f407a92c3dcd3b7145bef04fb8137724aadcf1cf0 + sha256: fea63576b3b7e02b2df8b78ba92b48ed66caec2bb041e9a0b1cbd586d5d80bfd url: "https://pub.dev" source: hosted - version: "3.18.4" + version: "3.23.1" win32: dependency: transitive description: @@ -1936,5 +1944,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.8.0-0 <4.0.0" - flutter: ">=3.27.0" + dart: ">=3.9.0 <4.0.0" + flutter: ">=3.35.0" diff --git a/pubspec.yaml b/pubspec.yaml index bf1ef611..47313f5b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,9 +1,9 @@ name: uae_stat description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness." publish_to: "none" -version: 1.0.68+69 -#version: 1.0.13+14 -#version: 1.0.5+5 +#version: 1.0.68+69 +#version: 1.0.15+16 +version: 1.0.6+6 environment: sdk: ">=3.2.3 <4.0.0" @@ -41,7 +41,7 @@ dependencies: flutter_secure_storage: ^10.0.0-beta.4 jwt_decoder: ^2.0.1 fluttertoast: ^8.2.11 - webview_flutter: ^4.5.0 + webview_flutter: ^4.13.0 video_player: ^2.8.5 flutter_carousel_widget: ^3.1.0 share_plus: ^10.1.1 @@ -80,6 +80,9 @@ dependencies: dotted_border: ^2.1.0 google_sign_in: ^7.1.1 flutter_web_auth_2: ^4.1.0 + flutter_uae_pass: ^1.1.0 + webview_flutter_android: ^4.10.5 + webview_flutter_wkwebview: ^3.23.1 dependency_overrides: fading_edge_scrollview: ^4.1.1