From 7935d944a2ca4217a4bc62c3c94d0a03e9350b5e Mon Sep 17 00:00:00 2001 From: Juki-shiba Date: Wed, 19 Feb 2025 18:28:24 +0530 Subject: [PATCH 1/3] fig fix --- .firebaserc | 2 +- android/app/src/main/AndroidManifest.xml | 18 ++ .../ae/gov/fcsc/frontend/MainActivity.java | 6 + .../ae/gov/fcsc/frontend/MainActivity.kt | 5 - firebase.json | 14 +- .../Screens/charts/screens/chart_screen.dart | 254 +++++++++++------- .../drawer_routes/Drawer Items/bookmark.dart | 26 +- .../drawer_routes/custom_drawer_routes.dart | 64 +++-- p/404.html | 33 +++ p/index.html | 89 ++++++ public/.well-known/assetlinks.json | 12 + 11 files changed, 370 insertions(+), 153 deletions(-) create mode 100644 android/app/src/main/java/ae/gov/fcsc/frontend/MainActivity.java delete mode 100644 android/app/src/main/kotlin/ae/gov/fcsc/frontend/MainActivity.kt create mode 100644 p/404.html create mode 100644 p/index.html create mode 100644 public/.well-known/assetlinks.json diff --git a/.firebaserc b/.firebaserc index 8c804c3e..f4483484 100644 --- a/.firebaserc +++ b/.firebaserc @@ -1,5 +1,5 @@ { "projects": { - "default": "uae-stats-demo" + "default": "fcsc-da580" } } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 6c6699ac..4e74a35d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -26,6 +26,24 @@ + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/java/ae/gov/fcsc/frontend/MainActivity.java b/android/app/src/main/java/ae/gov/fcsc/frontend/MainActivity.java new file mode 100644 index 00000000..f4c43bb3 --- /dev/null +++ b/android/app/src/main/java/ae/gov/fcsc/frontend/MainActivity.java @@ -0,0 +1,6 @@ +package ae.gov.fcsc.frontend; + +import io.flutter.embedding.android.FlutterActivity; + +public class MainActivity extends FlutterActivity { +} diff --git a/android/app/src/main/kotlin/ae/gov/fcsc/frontend/MainActivity.kt b/android/app/src/main/kotlin/ae/gov/fcsc/frontend/MainActivity.kt deleted file mode 100644 index 09aad86f..00000000 --- a/android/app/src/main/kotlin/ae/gov/fcsc/frontend/MainActivity.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ae.gov.fcsc.frontend - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() diff --git a/firebase.json b/firebase.json index 08b57089..ebf22e80 100644 --- a/firebase.json +++ b/firebase.json @@ -1,18 +1,6 @@ { - "flutter": { - "platforms": { - "dart": { - "lib/firebase_options.dart": { - "projectId": "uae-stats-demo", - "configurations": { - "web": "1:225888316715:web:b96ad37877684cd2dd296e" - } - } - } - } - }, "hosting": { - "public": "build/web", + "public": "p", "ignore": [ "firebase.json", "**/.*", diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index 22f1e054..e98179f5 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; @@ -17,6 +18,11 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart'; import '../filters/search_filter_helper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:path_provider/path_provider.dart'; +import 'dart:io'; class ChartScreen1 extends ConsumerStatefulWidget { final String dataSets; @@ -147,17 +153,17 @@ class _ChartScreen1State extends ConsumerState { }); // ToastUtil.showSuccessToast("Added to Bookmark."); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of(context)!.added_to_Bookmark, - style: TextStyle( - color: Color(0xFF2F692C), fontWeight: FontWeight.w600), - ), - backgroundColor: Color(0xFFD6E9C6), - duration: Duration(seconds: 2), - ), - ); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text( + // AppLocalizations.of(context)!.added_to_Bookmark, + // style: TextStyle( + // color: Color(0xFF2F692C), fontWeight: FontWeight.w600), + // ), + // backgroundColor: Color(0xFFD6E9C6), + // duration: Duration(seconds: 2), + // ), + // ); print("Bookmark added: ${response.id}"); } catch (e) { @@ -225,90 +231,90 @@ class _ChartScreen1State extends ConsumerState { } /// Show confirmation dialog before removing bookmark - void showRemoveBookmarkDialog() { - double myheight = MediaQuery.of(context).size.height; - showDialog( - context: context, - barrierDismissible: false, // User must tap button to dismiss dialog - builder: (context) => AlertDialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5.0), // Rounded corners - ), - contentPadding: EdgeInsets.zero, - content: Stack( - children: [ - Padding( - padding: const EdgeInsets.all(10.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - height: myheight / 30, - ), - Text( - context.translate( - 'Are you sure you want to remove this bookmark?', - 'هل أنت متأكد أنك تريد إزالة هذه الإشارة المرجعية؟'), - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - color: Color(0xFF898C81), - ), - ) - ], - ), - ), - ], - ), - actions: [ - SizedBox(height: 20), - SizedBox( - width: 100, // Set the desired width - child: TextButton( - onPressed: () => Navigator.pop(context), - style: TextButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - 10.0), // Adjust the radius as needed - ), - side: BorderSide( - color: Color(0xFFAA8E83), // Set the outline color - width: 1, // Set the border width - ), - ), - child: Text( - context.translate('No', 'لا'), - style: TextStyle( - color: Color(0xFFAA8E83), - fontSize: 16, - ), - ), - ), - ), - SizedBox( - width: 100, // Set the desired width - child: TextButton( - onPressed: () { - Navigator.pop(context); - removeBookmark(); // Close dialog - }, - style: TextButton.styleFrom( - backgroundColor: Color(0xFFAA8E83), // Set background color - foregroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), // Set text color - ), - ), - child: Text( - context.translate('Yes', 'نعم'), - style: TextStyle(color: Colors.white, fontSize: 16), - ), - ), - ), - ], - ), - ); - } + // void showRemoveBookmarkDialog() { + // double myheight = MediaQuery.of(context).size.height; + // showDialog( + // context: context, + // barrierDismissible: false, // User must tap button to dismiss dialog + // builder: (context) => AlertDialog( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(5.0), // Rounded corners + // ), + // contentPadding: EdgeInsets.zero, + // content: Stack( + // children: [ + // Padding( + // padding: const EdgeInsets.all(10.0), + // child: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // SizedBox( + // height: myheight / 30, + // ), + // Text( + // context.translate( + // 'Are you sure you want to remove this bookmark?', + // 'هل أنت متأكد أنك تريد إزالة هذه الإشارة المرجعية؟'), + // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 18, + // color: Color(0xFF898C81), + // ), + // ) + // ], + // ), + // ), + // ], + // ), + // actions: [ + // SizedBox(height: 20), + // SizedBox( + // width: 100, // Set the desired width + // child: TextButton( + // onPressed: () => Navigator.pop(context), + // style: TextButton.styleFrom( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular( + // 10.0), // Adjust the radius as needed + // ), + // side: BorderSide( + // color: Color(0xFFAA8E83), // Set the outline color + // width: 1, // Set the border width + // ), + // ), + // child: Text( + // context.translate('No', 'لا'), + // style: TextStyle( + // color: Color(0xFFAA8E83), + // fontSize: 16, + // ), + // ), + // ), + // ), + // SizedBox( + // width: 100, // Set the desired width + // child: TextButton( + // onPressed: () { + // Navigator.pop(context); + // removeBookmark(); // Close dialog + // }, + // style: TextButton.styleFrom( + // backgroundColor: Color(0xFFAA8E83), // Set background color + // foregroundColor: Colors.white, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10.0), // Set text color + // ), + // ), + // child: Text( + // context.translate('Yes', 'نعم'), + // style: TextStyle(color: Colors.white, fontSize: 16), + // ), + // ), + // ), + // ], + // ), + // ); + // } //when the popup need for bookmark // void showAddBookmarkDialog() { // double myheight = MediaQuery.of(context).size.height; @@ -400,9 +406,24 @@ class _ChartScreen1State extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - 'The bookmark is added successfully', + 'Added to Bookmark', + style: TextStyle(color: Colors.white, fontSize: 14), ), - backgroundColor: Colors.green, + backgroundColor: Colors.black, // Match the dark background + duration: Duration(seconds: 2), + ), + ); + } + + void showRemoveBookmarkDialog() { + removeBookmark(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Removed from BookMark', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + backgroundColor: Colors.black, // Match the dark background duration: Duration(seconds: 2), ), ); @@ -2052,7 +2073,7 @@ class _ChartScreen1State extends ConsumerState { GestureDetector( onTap: () { if (isBookmarked) { - showRemoveBookmarkDialog(); + showRemoveBookmarkDialog(); } else { showAddBookmarkDialog(); } @@ -2127,14 +2148,39 @@ class _ChartScreen1State extends ConsumerState { // width: 24, // height: 24, // ), + GestureDetector( + onTap: () async { + try { + final svgAssetPath = 'assets/images/sample.svg'; // Update with your actual path + final directory = await getTemporaryDirectory(); + final file = File('${directory.path}/shared_image.svg'); + + // Load the SVG asset and write to the temp file + final svgData = await DefaultAssetBundle.of(context).loadString(svgAssetPath); + await file.writeAsString(svgData); + + // Share the file + await Share.shareXFiles([XFile(file.path)], text: "Check this out!"); + } catch (e) { + print("Error sharing file: $e"); + } + }, + child: SvgPicture.asset( + UaeNumbersAssetPath.share, + semanticsLabel: 'share', + width: 24, + height: 24, + ), + ) - SvgPicture.asset( - UaeNumbersAssetPath.share, - semanticsLabel: 'share', - width: 24, - height: 24, - ), + + // SvgPicture.asset( + // UaeNumbersAssetPath.share, + // semanticsLabel: 'share', + // width: 24, + // height: 24, + // ), ], ) ], diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart index cf44f52a..5fac90a9 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart @@ -109,17 +109,17 @@ class _BookMarkState extends ConsumerState { 'Authorization': adminToken, }); // Show success SnackBar - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text( - 'Removed from Bookmark.', - style: TextStyle( - color: Color(0xFF2F692C), fontWeight: FontWeight.w600), - ), - backgroundColor: Color(0xFFD6E9C6), - duration: Duration(seconds: 2), - ), - ); + // ScaffoldMessenger.of(context).showSnackBar( + // const SnackBar( + // content: Text( + // 'Removed from Bookmark.', + // style: TextStyle( + // color: Color(0xFF2F692C), fontWeight: FontWeight.w600), + // ), + // backgroundColor: Color(0xFFD6E9C6), + // duration: Duration(seconds: 2), + // ), + // ); final locale = ref.read(localeProvider); fetchBookmarks(locale?.languageCode ?? 'en'); // ToastUtil.showSuccessToast("Removed from Bookmark."); @@ -329,9 +329,9 @@ class _BookMarkState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - 'The bookmark is removed successfully', + 'Removed from BookMark', ), - backgroundColor: Colors.green, + backgroundColor: Colors.black, duration: Duration(seconds: 2), ), ); diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 6f0a366c..52ade75c 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -799,23 +799,53 @@ class _BaseScaffoldState extends ConsumerState { SizedBox( width: mywidth / 20, ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Text(userId ?? 'Loading user...'), // Display userId here - // Text('Mohammad@fcsc.com') - if (userId == "guest") ...[ - Text(userName ?? 'Guest User'), - ] else ...[ - Text(userName ?? 'Loading...'), - Text( - userEmail ?? 'Loading...', - style: TextStyle(fontSize: 12), - // maxLines: 2, // Allow the text to wrap to the next line - overflow: TextOverflow.ellipsis, - ), - ] - ], + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // // Text(userId ?? 'Loading user...'), // Display userId here + // // Text('Mohammad@fcsc.com') + // if (userId == "guest") ...[ + // Text(userName ?? 'Guest User'), + // ] else ...[ + // Text(userName ?? 'Loading...'), + // Tooltip( + // message: userEmail ?? 'Loading...', + // child: Text( + // userEmail ?? 'Loading...', + // style: TextStyle(fontSize: 12), + // softWrap: true, + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // ), + // ), + // + // ] + // ], + // ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (userId == "guest") ...[ + Text(userName ?? 'Guest User'), + ] else ...[ + Text(userName ?? 'Loading...'), + Tooltip( + message: userEmail ?? 'Loading...', // Shows full email on hover + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.6, // Adjust width as needed + child: Text( + userEmail ?? 'Loading...', + style: TextStyle(fontSize: 12), + // softWrap: true, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + ), + ], + ], + ), ), ], ), diff --git a/p/404.html b/p/404.html new file mode 100644 index 00000000..829eda8f --- /dev/null +++ b/p/404.html @@ -0,0 +1,33 @@ + + + + + + Page Not Found + + + + +
+

404

+

Page Not Found

+

The specified file was not found on this website. Please check the URL for mistakes and try again.

+

Why am I seeing this?

+

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

+
+ + diff --git a/p/index.html b/p/index.html new file mode 100644 index 00000000..c78755d8 --- /dev/null +++ b/p/index.html @@ -0,0 +1,89 @@ + + + + + + Welcome to Firebase Hosting + + + + + + + + + + + + + + + + + + + +
+

Welcome

+

Firebase Hosting Setup Complete

+

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

+ Open Hosting Documentation +
+

Firebase SDK Loading…

+ + + + diff --git a/public/.well-known/assetlinks.json b/public/.well-known/assetlinks.json new file mode 100644 index 00000000..af8eb41b --- /dev/null +++ b/public/.well-known/assetlinks.json @@ -0,0 +1,12 @@ +[ + { + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "ae.gov.fcsc.frontend", + "sha256_cert_fingerprints": [ + "3D:BB:9E:B6:3E:80:50:6F:52:EB:73:B8:AD:F9:5F:5A:0A:05:BE:E4:CA:D1:AF:F7:26:2C:56:3F:35:1D:4E:81" + ] + } + } +] From 704c2d409f830d071c65e4db6f261a7a8104b8f8 Mon Sep 17 00:00:00 2001 From: Kalonkarthik Date: Thu, 20 Feb 2025 17:53:18 +0530 Subject: [PATCH 2/3] Validation message arabic Translated --- lib/l10n/intl_ar.arb | 2 +- lib/l10n/intl_en.arb | 2 +- .../auth_verification/create_new_pw.dart | 25 +- .../auth_verification/registration.dart | 71 +++--- lib/presentation/Screens/profilepage.dart | 14 +- .../routes/auth_routes/login_route.dart | 18 +- .../drawer_routes/Drawer Items/bookmark.dart | 218 +++++++++--------- .../Drawer Items/edit_profile.dart | 13 +- .../user_guide/AboutTheApp/AboutFCSC.dart | 16 +- .../user_guide/AboutTheApp/getStarted.dart | 13 +- .../user_guide/KeyFeatures/AppFeatures.dart | 13 +- .../KeyFeatures/ChangeMyPassword.dart | 26 +-- .../user_guide/KeyFeatures/EditMyProfile.dart | 21 +- .../user_guide/KeyFeatures/howUseTheApp.dart | 21 +- .../user_guide/KeyFeatures/purpose.dart | 19 +- .../user_guide/KeyFeatures/stayUpdate.dart | 20 +- .../user_guide/KeyFeatures/useTheApp.dart | 22 +- .../Drawer Items/user_guide/aboutApp.dart | 17 +- .../Drawer Items/user_guide/faq_page.dart | 37 +-- .../Drawer Items/user_guide/features.dart | 14 +- 20 files changed, 251 insertions(+), 351 deletions(-) diff --git a/lib/l10n/intl_ar.arb b/lib/l10n/intl_ar.arb index 2f586571..c272b10e 100644 --- a/lib/l10n/intl_ar.arb +++ b/lib/l10n/intl_ar.arb @@ -98,7 +98,7 @@ "failed_to_update_password": "", "password_update_successfully": "تم تحديث كلمة المرور بنجاح.", "new_password_not_same_as_old": "كلمة المرور الجديدة يجب ألا تكون نفس كلمة المرور القديمة", - "password_between_8_to_40": "يجب أن تتراوح كلمة المرور بين 8 و64 حرفًا", + "password_between_8_to_40": "يجب أن تتراوح كلمة المرور بين 8 و40 حرفًا", "new_password_required": "كلمة المرور الجديدة مطلوبة", "old_password_is_required": "كلمة المرور القديمة مطلوبة", "confirm_password_is_required": "تأكيد كلمة المرور مطلوب", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index f6217299..8f5fba5a 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -99,7 +99,7 @@ "failed_to_update_password": "", "password_update_successfully": "Password updated successfully.", "new_password_not_same_as_old": "New password must not be the same as the old password", - "password_between_8_to_40": "Password must be between 8 and 64 characters", + "password_between_8_to_40": "Password must be between 8 and 40 characters", "new_password_required": "New password is required", "old_password_is_required": "Old password is required", "confirm_password_is_required": "Confirm password is required", diff --git a/lib/presentation/Screens/auth_verification/create_new_pw.dart b/lib/presentation/Screens/auth_verification/create_new_pw.dart index be8a8564..0b8de8da 100644 --- a/lib/presentation/Screens/auth_verification/create_new_pw.dart +++ b/lib/presentation/Screens/auth_verification/create_new_pw.dart @@ -220,14 +220,7 @@ class _CreateNewPwState extends ConsumerState { children: [ GestureDetector( onTap: () { - - if (widget.keyParam == 'editProfile') { - context.go('/editProfile'); - }else - { - context.go('/profile/${widget.userId}'); - } - + context.pop(); }, child: Container( margin: EdgeInsets.only(top: 10,left: 1,bottom: 16,right: 1), // Add margin for positioning @@ -249,7 +242,13 @@ class _CreateNewPwState extends ConsumerState { pathColorWhenOn: Colors.grey.shade300, pathColorWhenOff: Colors.grey.shade300, onTap: () { + final formState = _formKey.currentState; ref.read(localeProvider.notifier).toggleLocale(); + Future.delayed(Duration(milliseconds: 100), () { + if (formState?.validate() == false) { + formState?.validate(); + } + }); }, ); }, @@ -658,7 +657,7 @@ class _CreateNewPwState extends ConsumerState { SizedBox(height: 10), ElevatedButton( onPressed: () async { - context.go('/'); + context.go('/login'); }, style: ButtonStyle( shape: WidgetStatePropertyAll( @@ -697,6 +696,14 @@ class _CreateNewPwState extends ConsumerState { 'Login', 'تسجيل الدخول', ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'Roboto', + ), + fontSize: 17, + fontWeight: FontWeight.w500, + ), ), 6.horizontalSpace, const Icon(Icons.chevron_right_outlined,color:Colors.white), diff --git a/lib/presentation/Screens/auth_verification/registration.dart b/lib/presentation/Screens/auth_verification/registration.dart index 36eb6a9a..aa9166d0 100644 --- a/lib/presentation/Screens/auth_verification/registration.dart +++ b/lib/presentation/Screens/auth_verification/registration.dart @@ -7,12 +7,13 @@ import 'package:go_router/go_router.dart'; import 'package:pocketbase/pocketbase.dart'; import 'package:uae_stat/config/my_theme.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/presentation/Screens/profilepage.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; -import '../../components/my_toggle.dart'; +import 'package:uae_stat/presentation/components/my_toggle.dart'; import '../../routes/auth_routes/login_route.dart'; class RegisterScreen extends ConsumerStatefulWidget { @@ -120,10 +121,10 @@ class _RegisterScreenState extends ConsumerState { if (value == null || value.isEmpty) { return context.translate('Required', 'مطلوب'); } else if (value.length > 40) { - return 'Must not exceed 40 characters'; + return AppLocalizations.of(context)!.only40charac; } else if (!RegExp(r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF]+$") .hasMatch(value)) { - return 'Invalid Characters'; + return AppLocalizations.of(context)!.invalid_characters; } return null; } @@ -138,7 +139,7 @@ class _RegisterScreenState extends ConsumerState { if (value == null || value.isEmpty) { return context.translate('Required', 'مطلوب'); } else if (!RegExp(emailRegex).hasMatch(value)) { - return 'Invalid Email'; + return AppLocalizations.of(context)!.invalid_email; } return null; } @@ -157,38 +158,38 @@ class _RegisterScreenState extends ConsumerState { if (value == null || value.isEmpty) { return context.translate('Required', 'مطلوب'); } else if (value.length < 8) { - return 'Password must be at least 8characters'; + return AppLocalizations.of(context)!.only8charac; } // Check the length constraint - if (value.length < 8 || value.length > 64) { - return 'Password must be between 8 and 64 characters'; + if (value.length < 8 || value.length > 40) { + return AppLocalizations.of(context)!.password_between_8_to_40; } // Check the regular expression if (!regex.hasMatch(value)) { - return 'Password contains invalid characters'; + return AppLocalizations.of(context)!.password_invalid; } // Track missing constraints List missingConstraints = []; if (!hasUppercase.hasMatch(value)) { - missingConstraints.add('uppercase letter'); + missingConstraints.add(context.translate('uppercase letter','حرف كبير')); } if (!hasLowercase.hasMatch(value)) { - missingConstraints.add('lowercase letter'); + missingConstraints.add(context.translate('lowercase letter','حرف صغير')); } if (!hasDigit.hasMatch(value)) { - missingConstraints.add('numeric digit'); + missingConstraints.add(context.translate('numeric digit','رقم')); } if (!hasSpecialCharacter.hasMatch(value)) { - missingConstraints.add('special character'); + missingConstraints.add(context.translate('special character','رمز خاص')); } // If there are missing constraints, return a consolidated message if (missingConstraints.isNotEmpty) { - return 'At least one ${missingConstraints.join(', ')}'; + return context.translate('At least one ${missingConstraints.join(', ')}','${missingConstraints.join(', ')}على الأقل واحد '); } _password = value; // Store the password for confirm password validation @@ -203,11 +204,12 @@ class _RegisterScreenState extends ConsumerState { if (value == null || value.isEmpty) { return context.translate('Required', 'مطلوب'); } else if (value.length < 8 || value.length > 40) { - return 'Password must be at least 8characters'; + return AppLocalizations.of(context)!.password_between_8_to_40; } else if (!regex.hasMatch(value)) { - return 'Password contains invalid characters'; + return AppLocalizations.of(context)!.password_invalid; } else if (value != _password) { - return 'Passwords do not match'; + return AppLocalizations.of(context)!.password_match; + ; } return null; @@ -261,7 +263,7 @@ class _RegisterScreenState extends ConsumerState { // Check if the error is due to an invalid or already used email if (e .toString() - .contains('The email is invalid or already in use.')) { + .contains(AppLocalizations.of(context)!.email_invalid)) { showDialog( context: context, builder: (context) { @@ -321,6 +323,11 @@ class _RegisterScreenState extends ConsumerState { } } + final fcscBanner = Image.asset( + BannerAssetPath.fcsc, + height: 40, + ); + @override Widget build(BuildContext context) { double screenheight = MediaQuery.of(context).size.height; @@ -376,7 +383,13 @@ class _RegisterScreenState extends ConsumerState { pathColorWhenOn: Colors.grey.shade300, pathColorWhenOff: Colors.grey.shade300, onTap: () { + final formState = _formKey.currentState; ref.read(localeProvider.notifier).toggleLocale(); + Future.delayed(Duration(milliseconds: 100), () { + if (formState?.validate() == false) { + formState?.validate(); + } + }); }, ); }, @@ -1224,17 +1237,19 @@ class _RegisterScreenState extends ConsumerState { height: 10, ), Center( - 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: 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: 20, ), diff --git a/lib/presentation/Screens/profilepage.dart b/lib/presentation/Screens/profilepage.dart index 6a1ec4a6..c93f003f 100644 --- a/lib/presentation/Screens/profilepage.dart +++ b/lib/presentation/Screens/profilepage.dart @@ -273,7 +273,7 @@ class _ProfileScreenState extends ConsumerState { // Function to validate the DOB field String? _validateDob(String? value) { if (value == null || value.isEmpty) { - return 'Required'; + return context.translate('Required', 'مطلوب'); } final DateTime selectedDate = _selectedDate!; @@ -281,14 +281,14 @@ class _ProfileScreenState extends ConsumerState { // Check if the selected date is in the future if (selectedDate.isAfter(today)) { - return 'Date of birth cannot be in the future'; + return context.translate('Date of birth cannot be in the future','لا يمكن أن يكون تاريخ الميلاد في المستقبل'); } return null; } String? _validateDropdown(String? value) { if (value == null || value.isEmpty) { - return 'Required'; + return context.translate('Required', 'مطلوب'); } return null; } @@ -657,7 +657,7 @@ class _ProfileScreenState extends ConsumerState { enabled: true, validator: (value) { if (value == null || value.isEmpty) { - return 'Required'; + return context.translate('Required', 'مطلوب'); } //RegExp(r"^[a-zA-Z\s]+$"); @@ -665,7 +665,7 @@ class _ProfileScreenState extends ConsumerState { r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$"); if (!nameRegex.hasMatch(value)) { - return 'Invalid Characters'; + return AppLocalizations.of(context)!.invalid_characters; } return null; }, @@ -912,7 +912,7 @@ class _ProfileScreenState extends ConsumerState { Padding( padding: const EdgeInsets.only(left: 10.0), child: Text( - 'Required', + context.translate('Required', 'مطلوب'), style: TextStyle( color: Color(0xFFb22222), fontSize: 12, @@ -928,7 +928,7 @@ class _ProfileScreenState extends ConsumerState { final userId = widget.userId; final email = _emailController.text; - context.go('/createNewPw/$userId/$email'); + context.push('/createNewPw/$userId/$email'); }, child: Text( AppLocalizations.of(context)!.change_password, diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index df4ecb23..53bbf143 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -24,6 +24,8 @@ import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_r import 'package:http/http.dart' as http; import '../../Screens/auth_verification/registration.dart'; import 'package:pocketbase/pocketbase.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + import '../../components/indicators/locale_provider.dart'; import '../../components/my_toggle.dart'; @@ -451,7 +453,7 @@ class LoginRoute extends HookConsumerWidget { ), fontSize: locale?.languageCode == 'ar' ? 12: 18, fontWeight: FontWeight.w500, - ) + ), ), 6.horizontalSpace, const Icon( @@ -473,10 +475,14 @@ class LoginRoute extends HookConsumerWidget { ), validator: (value) { + final emailRegex = + r'^[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+@[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+\.[a-zA-Z]{2,}$'; if (value == null || value.isEmpty) { return context.translate('Required', 'مطلوب'); } - return FieldValidator.email()(value); + else if (!RegExp(emailRegex).hasMatch(value)) { + return AppLocalizations.of(context)!.invalid_email; + } return null; }, imgPath: MiscIconAssetPath.person, controller: emailCtl, @@ -487,7 +493,7 @@ class LoginRoute extends HookConsumerWidget { if (text == null || text.isEmpty) { return context.translate('Required', 'مطلوب'); } else if (text.length < 8) { - return 'The password must be at least 8 characters'; + return AppLocalizations.of(context)!.only8charac; } return FieldValidator.password(minLength: 8)(text); }, @@ -668,7 +674,13 @@ class LoginRoute extends HookConsumerWidget { pathColorWhenOn: Colors.grey.shade300, pathColorWhenOff: Colors.grey.shade300, onTap: () { + final formState = formKey.currentState; ref.read(localeProvider.notifier).toggleLocale(); + Future.delayed(Duration(milliseconds: 100), () { + if (formState?.validate() == false) { + formState?.validate(); + } + }); }, ), ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart index cf44f52a..e4f33c07 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart @@ -140,90 +140,96 @@ class _BookMarkState extends ConsumerState { } /// Show confirmation dialog before removing bookmark - // void showRemoveBookmarkDialog(id) { - // double myheight = MediaQuery.of(context).size.height; - // showDialog( - // context: context, - // barrierDismissible: false, // User must tap button to dismiss dialog - // builder: (context) => AlertDialog( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(5.0), // Rounded corners - // ), - // contentPadding: EdgeInsets.zero, - // content: Stack( - // children: [ - // Padding( - // padding: const EdgeInsets.all(10.0), - // child: Column( - // mainAxisSize: MainAxisSize.min, - // children: [ - // SizedBox( - // height: myheight / 30, - // ), - // Text( - // context.translate( - // 'Are you sure you want to remove this bookmark?', - // 'هل أنت متأكد أنك تريد إزالة هذه الإشارة المرجعية؟'), - // textAlign: TextAlign.center, - // style: TextStyle( - // fontSize: 18, - // color: Color(0xFF898C81), - // ), - // ) - // ], - // ), - // ), - // ], - // ), - // actions: [ - // SizedBox(height: 20), - // SizedBox( - // width: 100, // Set the desired width - // child: TextButton( - // onPressed: () => Navigator.pop(context), - // style: TextButton.styleFrom( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular( - // 10.0), // Adjust the radius as needed - // ), - // side: BorderSide( - // color: Color(0xFFAA8E83), // Set the outline color - // width: 1, // Set the border width - // ), - // ), - // child: Text( - // context.translate('No', 'لا'), - // style: TextStyle( - // color: Color(0xFFAA8E83), - // fontSize: 16, - // ), - // ), - // ), - // ), - // SizedBox( - // width: 100, // Set the desired width - // child: TextButton( - // onPressed: () { - // Navigator.pop(context); - // removeBookmark(id); // Close dialog - // }, - // style: TextButton.styleFrom( - // backgroundColor: Color(0xFFAA8E83), // Set background color - // foregroundColor: Colors.white, - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(10.0), // Set text color - // ), - // ), - // child: Text( - // context.translate('Yes', 'نعم'), - // style: TextStyle(color: Colors.white, fontSize: 16), - // ), - // ), - // ), - // ], - // ), - // ); - // } + void showRemoveBookmarkDialog(id) { + double myheight = MediaQuery.of(context).size.height; + showDialog( + context: context, + barrierDismissible: false, // User must tap button to dismiss dialog + builder: (context) => AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), // Rounded corners + ), + contentPadding: EdgeInsets.zero, + content: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: myheight / 30, + ), + Text( + context.translate( + 'Are you sure you want to remove this bookmark?', + 'هل أنت متأكد أنك تريد إزالة هذه الإشارة المرجعية؟'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + color: Color(0xFF898C81), + ), + ) + ], + ), + ), + ], + ), + actions: [ + SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox( + width: 100, // Set the desired width + child: TextButton( + onPressed: () => Navigator.pop(context), + style: TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 10.0), // Adjust the radius as needed + ), + side: BorderSide( + color: Color(0xFFAA8E83), // Set the outline color + width: 1, // Set the border width + ), + ), + child: Text( + context.translate('No', 'لا'), + style: TextStyle( + color: Color(0xFFAA8E83), + fontSize: 16, + ), + ), + ), + ), + SizedBox( + width: 100, // Set the desired width + child: TextButton( + onPressed: () { + Navigator.pop(context); + removeBookmark(id); // Close dialog + }, + style: TextButton.styleFrom( + backgroundColor: Color(0xFFAA8E83), // Set background color + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), // Set text color + ), + ), + child: Text( + context.translate('Yes', 'نعم'), + style: TextStyle(color: Colors.white, fontSize: 16), + ), + ), + ), + ], + ) + + ], + ), + ); + } String colorToHex(Color color) { return '0xFF${color.red.toRadixString(16).padLeft(2, '0').toUpperCase()}' @@ -322,19 +328,31 @@ class _BookMarkState extends ConsumerState { ), ), ), + // GestureDetector( + // onTap: () { + // debugPrint("Icon clicked in: ${data['title']}"); + // removeBookmark(data['id']); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text( + // 'The bookmark is removed successfully', + // ), + // backgroundColor: Colors.green, + // duration: Duration(seconds: 2), + // ), + // ); + // }, + // child: const Icon( + // Icons.delete, + // color: Colors.black, + // size: 20, + // ), + // ), + GestureDetector( onTap: () { debugPrint("Icon clicked in: ${data['title']}"); - removeBookmark(data['id']); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - 'The bookmark is removed successfully', - ), - backgroundColor: Colors.green, - duration: Duration(seconds: 2), - ), - ); + showRemoveBookmarkDialog(data['id']); }, child: const Icon( Icons.bookmarks_rounded, @@ -342,18 +360,6 @@ class _BookMarkState extends ConsumerState { size: 20, ), ), - - // GestureDetector( - // onTap: () { - // debugPrint("Icon clicked in: ${data['title']}"); - // // showRemoveBookmarkDialog(data['id']); - // }, - // child: const Icon( - // Icons.bookmarks_rounded, - // color: Colors.black, - // size: 20, - // ), - // ), ], ), Text( 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 42280b3b..82765c23 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -13,6 +13,7 @@ import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:uae_stat/config/my_theme.dart'; +import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; @@ -298,7 +299,7 @@ class _EditProfileState extends State { // Function to validate the DOB field String? _validateDob(String? value) { if (value == null || value.isEmpty) { - return 'Required'; + return context.translate('Required', 'مطلوب'); } final DateTime selectedDate = _selectedDate!; @@ -306,14 +307,14 @@ class _EditProfileState extends State { // Check if the selected date is in the future if (selectedDate.isAfter(today)) { - return 'Date of birth cannot be in the future'; + return context.translate('Date of birth cannot be in the future','لا يمكن أن يكون تاريخ الميلاد في المستقبل'); } return null; } String? _validateDropdown(String? value) { if (value == null || value.isEmpty) { - return 'Required'; + return context.translate('Required', 'مطلوب'); } return null; } @@ -689,7 +690,7 @@ class _EditProfileState extends State { enabled: false, validator: (value) { if (value == null || value.isEmpty) { - return 'Required'; + return context.translate('Required', 'مطلوب'); } //RegExp(r"^[a-zA-Z\s]+$"); @@ -697,7 +698,7 @@ class _EditProfileState extends State { r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$", ); if (!nameRegex.hasMatch(value)) { - return 'Invalid Characters'; + return AppLocalizations.of(context)!.invalid_characters; } return null; }, @@ -956,7 +957,7 @@ class _EditProfileState extends State { child: GestureDetector( onTap: () { final email = _emailController.text; - context.go( + context.push( '/createNewPw/$userId/$email?key=editProfile'); }, child: Text( diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart index 8f5a8543..5c63feb8 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/AboutFCSC.dart @@ -3,18 +3,11 @@ import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; - class aboutFCSC extends StatelessWidget { const aboutFCSC({super.key}); @override Widget build(BuildContext context) { - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); return BaseScaffold( showDivider: true, showBackButton: true, @@ -86,15 +79,10 @@ class aboutFCSC extends StatelessWidget { ], ), ), - SizedBox(height: MediaQuery.of(context).size.height*0.15), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), SizedBox( - height: 25, + height: 20, ), - ]), + ],), ), ), ); diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart index 78835c9d..e6b1e33c 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/AboutTheApp/getStarted.dart @@ -3,18 +3,12 @@ import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; class GetStarted extends StatelessWidget { const GetStarted({super.key}); @override Widget build(BuildContext context) { - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); return Theme( data: ThemeData( fontFamily: 'Roboto', // Set default font family for this page @@ -84,12 +78,7 @@ class GetStarted extends StatelessWidget { SizedBox( height:MediaQuery.of(context).size.height * 0.12, ), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox(height: 25,), - + SizedBox(height: 20,), ], ), ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart index 3b834f03..a58e852c 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/AppFeatures.dart @@ -6,11 +6,7 @@ import '../../../custom_drawer_routes.dart'; class AppFeatures extends StatelessWidget { AppFeatures({super.key}); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + @override Widget build(BuildContext context) { return Theme( @@ -205,12 +201,7 @@ class AppFeatures extends StatelessWidget { ], ), ), - SizedBox(height: 25,), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox(height: 25,), + SizedBox(height: 20,), ], ), ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart index 64d20ad8..a6b2a8ad 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/ChangeMyPassword.dart @@ -1,16 +1,9 @@ import 'package:flutter/material.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; - -import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart'; -import '../../../custom_drawer_routes.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; class ChangeMyPassword extends StatelessWidget { - ChangeMyPassword({super.key}); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + const ChangeMyPassword({super.key}); @override Widget build(BuildContext context) { return Theme( @@ -116,7 +109,7 @@ class ChangeMyPassword extends StatelessWidget { style: TextStyle( fontWeight: FontWeight.w600, color: Color(0xFF414042), - fontFamily: 'Roboto' + fontFamily: 'Roboto', ),), TextSpan(text:context.translate( ' link at the bottom.', @@ -295,9 +288,9 @@ class ChangeMyPassword extends StatelessWidget { style: TextStyle( fontWeight: FontWeight.w600, color: Color(0xFF414042), - fontFamily: 'Roboto' + fontFamily: 'Roboto', ),), - TextSpan(text: context.translate('button',''),) + TextSpan(text: context.translate('button',''),), ], ), ), @@ -360,14 +353,7 @@ class ChangeMyPassword extends StatelessWidget { ], ), ), - - SizedBox(height: 25,), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox(height: 25,), - + SizedBox(height: 20,), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart index 3a8ff898..ac52029a 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/EditMyProfile.dart @@ -1,16 +1,12 @@ import 'package:flutter/material.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; -import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart'; -import '../../../custom_drawer_routes.dart'; + +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; class EditMyProfile extends StatelessWidget { - EditMyProfile({super.key}); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + const EditMyProfile({super.key}); + @override Widget build(BuildContext context) { return Theme( @@ -457,14 +453,7 @@ class EditMyProfile extends StatelessWidget { ], ), ), - - SizedBox(height: 25,), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox(height: 25,), - + SizedBox(height: 20,), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart index 1d61194e..ed84871f 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/howUseTheApp.dart @@ -1,16 +1,12 @@ import 'package:flutter/material.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; -import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart'; -import '../../../custom_drawer_routes.dart'; + +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; class HowUseTheApp extends StatelessWidget { - HowUseTheApp({super.key}); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + const HowUseTheApp({super.key}); + @override Widget build(BuildContext context) { return Theme( @@ -203,14 +199,7 @@ class HowUseTheApp extends StatelessWidget { ], ), SizedBox( - height: 25, - ), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox( - height: 25, + height: 20, ), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart index eae4c7cb..99e08a72 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/purpose.dart @@ -1,16 +1,10 @@ import 'package:flutter/material.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; -import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart'; -import '../../../custom_drawer_routes.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; class Purpose extends StatelessWidget { - Purpose({super.key}); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + const Purpose({super.key}); @override Widget build(BuildContext context) { return Theme( @@ -151,14 +145,7 @@ class Purpose extends StatelessWidget { ], ), SizedBox( - height: 40, - ), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox( - height: 25, + height: 20, ), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart index 85ec7ce7..78b8f8ca 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/stayUpdate.dart @@ -1,16 +1,11 @@ import 'package:flutter/material.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; -import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart'; -import '../../../custom_drawer_routes.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; class StayUpdate extends StatelessWidget { - StayUpdate({super.key}); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + const StayUpdate({super.key}); + @override Widget build(BuildContext context) { return Theme( @@ -91,14 +86,7 @@ class StayUpdate extends StatelessWidget { ], ), SizedBox( - height: 150, - ), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox( - height: 25, + height: 20, ), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart index b2720689..ad2f41dc 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/KeyFeatures/useTheApp.dart @@ -1,16 +1,10 @@ import 'package:flutter/material.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; - -import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart'; -import '../../../custom_drawer_routes.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; class WhoUseTheApp extends StatelessWidget { - WhoUseTheApp({super.key}); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + const WhoUseTheApp({super.key}); + @override Widget build(BuildContext context) { return Theme( @@ -141,15 +135,9 @@ class WhoUseTheApp extends StatelessWidget { ), ], ), + SizedBox( - height: 50, - ), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox( - height: 25, + height: 20, ), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart index fa53a0b8..8454db74 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/aboutApp.dart @@ -3,18 +3,12 @@ import 'package:go_router/go_router.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; -import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; class aboutTheApp extends StatelessWidget { const aboutTheApp({super.key}); @override Widget build(BuildContext context) { - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); return BaseScaffold( showDivider: true, showBackButton: true, @@ -67,7 +61,7 @@ class aboutTheApp extends StatelessWidget { border: Border( bottom: BorderSide( color: Colors.grey.shade300, - width: 0.5), // Grey bottom line + width: 0.5,), // Grey bottom line ), ), child: ListTile( @@ -87,17 +81,12 @@ class aboutTheApp extends StatelessWidget { trailing: Icon(Icons.keyboard_arrow_right), shape: Border( bottom: BorderSide( - color: Colors.black, width: 3), // Grey bottom line + color: Colors.black, width: 3,), // Grey bottom line ), ), ), - Spacer(), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), SizedBox( - height: 25, + height: 20, ), ], ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart index 6511c91a..4b354932 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; -import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; - import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; class FAQPage extends StatefulWidget { @@ -12,11 +10,7 @@ class FAQPage extends StatefulWidget { } class _FAQPageState extends State { - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + @override Widget build(BuildContext context) { return BaseScaffold( @@ -44,14 +38,7 @@ class _FAQPageState extends State { radius: Radius.circular(10), interactive: true, child: SingleChildScrollView( - child: Column( - children: [ - QuestionAnswerScrollView(), - SizedBox(height: 25,), - fcscBanner, - SizedBox(height: 25,), - ], - ), + child: QuestionAnswerScrollView(), ), ), ), @@ -83,24 +70,24 @@ class QuestionAnswerScrollView extends StatelessWidget { text: 'Yes, the app is strictly for registered and approved users. To access the data:\n\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), TextSpan( text: ' 1. You need to sign up using the Register Now option on the login screen.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), TextSpan( text: ' 2. Your registration must be approved by the admin.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), TextSpan( text: " 3. Once approved, you can log in to access the app's features and datasets.\n\nGuest access is not available for this application.\n ", style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), ], ), @@ -112,24 +99,24 @@ class QuestionAnswerScrollView extends StatelessWidget { text: 'نعم، التطبيق مخصص فقط للمستخدمين المسجلين والمعتمدين. للوصول إلى البيانات:\n\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), TextSpan( text: ' 1. يجب عليك التسجيل باستخدام خيار "التسجيل الآن" في شاشة تسجيل الدخول.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), TextSpan( text: ' 2. يجب أن يتم الموافقة على تسجيلك من قبل المسؤول.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), TextSpan( text: - " بعد الموافقة، يمكنك تسجيل الدخول للوصول إلى ميزات التطبيق وبياناته.\n\n لا يتوفر الوصول للزوار في هذا التطبيق.\n", + ' بعد الموافقة، يمكنك تسجيل الدخول للوصول إلى ميزات التطبيق وبياناته.\n\n لا يتوفر الوصول للزوار في هذا التطبيق.\n', style: TextStyle( - color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'), + color: Colors.grey, fontSize: 16, fontFamily: 'Roboto',), ), ], ), @@ -140,7 +127,7 @@ class QuestionAnswerScrollView extends StatelessWidget { 'question-ar': 'كيف يمكنني التنقل عبر التطبيق؟', 'answer': '• Use the main categories on the homepage (e.g., Economy, Environment) to access subcategories and detailed KPIs.\n• Drill down into specific metrics or graphical views by tapping on a KPI.\n• Access additional features like Bookmarks or Profile through the navigation bar.\n', - 'answer-ar': '•استخدم الفئات الرئيسية الموجودة على الصفحة الرئيسية (مثل: الاقتصاد، البيئة) للوصول إلى الفئات الفرعية ومؤشرات الأداء الرئيسية التفصيلية •\n\ قم بالتعمق في مؤشرات معينة أو عرض الرسوم البيانية من خلال النقر على مؤشر الأداء الرئيسي (KPI). \n • للوصول إلى ميزات إضافية مثل الإشارات المرجعية أو الملف الشخصي، استخدم شريط التنقل.\n', + 'answer-ar': '•استخدم الفئات الرئيسية الموجودة على الصفحة الرئيسية (مثل: الاقتصاد، البيئة) للوصول إلى الفئات الفرعية ومؤشرات الأداء الرئيسية التفصيلية •\n قم بالتعمق في مؤشرات معينة أو عرض الرسوم البيانية من خلال النقر على مؤشر الأداء الرئيسي (KPI). \n • للوصول إلى ميزات إضافية مثل الإشارات المرجعية أو الملف الشخصي، استخدم شريط التنقل.\n', }, { 'question': 'What types of data are available?', diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart index 216d3bb8..d0207db1 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart @@ -11,11 +11,7 @@ class UsingFeatures extends StatelessWidget { @override Widget build(BuildContext context) { - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - alignment: Alignment.center, - ); + return BaseScaffold( showDivider: true, showBackButton: true, @@ -237,14 +233,6 @@ class UsingFeatures extends StatelessWidget { ), ), ), - Spacer(), - Align( - alignment: Alignment.bottomCenter, - child: fcscBanner, - ), - SizedBox( - height: 30, - ), ], ), ), From c87985381618a66d3242a8921a070b82da576d93 Mon Sep 17 00:00:00 2001 From: Juki-shiba Date: Thu, 20 Feb 2025 18:03:51 +0530 Subject: [PATCH 3/3] drawer change --- android/app/src/main/AndroidManifest.xml | 1 + assets/edit_profile/profile.jpg | Bin 0 -> 2111 bytes assets/edit_profile/profile.png | Bin 26397 -> 0 bytes .../Screens/charts/screens/chart_screen.dart | 101 ++++++++++-------- .../Drawer Items/edit_profile.dart | 2 +- .../drawer_routes/custom_drawer_routes.dart | 87 ++++++++++++++- pubspec.lock | 8 ++ pubspec.yaml | 1 + 8 files changed, 153 insertions(+), 47 deletions(-) create mode 100644 assets/edit_profile/profile.jpg delete mode 100644 assets/edit_profile/profile.png diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 4e74a35d..a570820b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ + enskYX@Kb3`J|2`BH%8Ob$? z;}Sv-LfkwugvvXQ9!%1N(uo|x{Y}=ob^qwDbw7LUy+6Ot_xamv@AcvJ7Xa%(v8MnS z3;-B3!1@Gi*xts*i{^ZYV*e9)!yo_>H*>rkE2A?i;W1e&4(TyD&D^X zDDUE+I6DA+`rq;SUoysz5l)93-a}K11r>*y#X}q)u)%f2+;@YUi8+TI%7%PsV$M43 zYy)vWi0cG=!+pQu^iY=A{}SY57912It|f-JV;Kh1)dkwo&{PHCz!^}%0rCGs-w;9y z05Dkq0Fm}p^UVREh6})!k*}H-9{~9a0Ni=>Rr`7-p*}31FX@ob3itO1;6pJ0vK{~^ zJO)7O*cThLe5W@eWKxCt3V}ud2m%a11onUl=)eGCM!*n|fbse$umK3T7~&NH0V#v3I*Z+E7_NxW#4{WI&KU3VM;Uj`Q`^`M$+Kn-4 zU@3{Ue>xu@ms(}o&m~J#lvP~KigVtFRJV0IY1?;s^l+dD!iV)|+ZI!va)Z;pQuX7j zf$v%x4JQ_&+7ml9hhOo6t~bpejA=eYxU~{u)mo6GBjp)(F(I{(l$g}orL;4;xOpNZtS?ahiMWN#P7&)3}Dv(=rGK4QP+ zCTTk_ufxLsp2-!)vr|8uO02RPQeu^n&YxDvyz^QRIh0Y?gMT(Mxy0qxHZYEKb#H#n z4@gcw*TF@+bqFoCdy{K28SSSm-5r-95)ohJ&Z0u&A2MV7o|G=R6h`dLeZUitKE)`k zxEog?cZ@eU7|WPP{)O|*!sD`!DRa0T{+5Wk)9m zsg__7F))90aY&<8Z=fw#_tH;Q%zM&WCzID4PG#^5m&{wK1552~j3U{rN}9(bkBMnQ zKMU2b{;{n@-d3c`uJ~vBRC;H-%+&zI6!)&lTJP!QS=W*3x?kNS?8dN>IP0PzrC|EC zaE{$+c4dAuXVhQE$}-bg(Y``t$-vv=>jS+>FwDi^6GFHqE=DW=&GteBT(L zMR`=Xmsg!{u-4QcZ2g_`B!a>5LK>4@ERtMNW2mJRJuqLfg_n0ZOQgkGcvHG!>XROn zty*~r%Y>DECWGy3qO7Q#pZAo?e}r`$8p`jZ_tZRDyHaTles}V^$=SJ8=X3ZvVB0UV z?&CG}$uZ@_w@$RoKU{sRVXu{OP&lZYc)fOeDSK?!S?`YQo0m3o;v70-Ii!rpbHdA> zj}?zkN3{!1%xoV^o`}>V&gUDWVU}qp50rkg8QGhX+YSUb~KpB|6v{c5zp?d zDDtp&HYTRn9!@N0&(yiQ2o0+>j=cOk5A)Ym=81E+lGo}7A{{FX-_I_@kXTE+29Hxn z4O+xM42sODM&@?!1SUNa@0UllXUleDF&Z_Qi!%jbbq(=rz1TBcA!;am*kz)qM|ECh z8{cSGNSJCSJ>YCbd8#%=wIQ&HqSk))j(I|1=+;!(k{P9K7aCKhHjlQwG&Lf;VTg(c z;~CHc#b2B(mY)q{UT(ojwaIp!Hx;CT>l$x}1kVIZ&(!dPL5tU#19P>Tx`n>C6A&+D z&Iw<4xL+smOX?HGD1x`2ldMBj)95~D%gd?8r_CBdYTV2(1~000$Qmd1Rg20G`EbeF z`-^1v6Z9OrAH5*3cGSBbrj_z_Q~-*o%egXt_-~ zA*E9g7twl9p1wD#BfHHmTiI=Dh6=sa_dgP9qvGxLvh#+_Ebc8O@*CTK%*z&y4^vuV zdKyxh)Opt|pDa&@>hpy`)~X5ooS!*y=xTe2@@#KrlrsE72c6QsVs4$loO3Y zkH!ml`i}_@nbg}fr85M|^L;6A9eu}pR%)90^f}3o9@A%4yeAz0w(Ga#p=+OaY*xRJ zJgptggsNLLF7bkId@!<$*5`zF(Vc{TOq&q>RSDBt&ixtxv|m0v4cylBaMvDh%Ou1i dqJOo0SZ;>wN|q{x$5jFr{HB!?8BbV$`fuls{ufAV1&-h}|faWLhG*AAe5s1wuCQ zU^65p2>)ULg6YOsySA#H1y4qZm#g(;YD=IZ#yLM@6eq%%C zHkRcpXD&1Y$27Rso$lH^X22=WODZS+EHK3nBm?ZcR@M@^G`B3*mNq2Am-_mvQmU4vUMWch zuYqzPwQ^a~Fl#QiQWCtGX32}MU!0%$m;dEU@@8{o8uz;w_vQUh;Pq?(hIs9@V>9vt zcKpCFz<~otrXkJu<8{Qn^(-XxnP2+oz4D>GJEzN~Pzi$fRJA9mNGB0l!~fzm70_Pr zLl&0S<-(N}X?0>58LY~1qYfS^Nel{BFdKC+Lah|Z2EMz5bJ}2-5Z8+^RjaG(vb@}q z!FqkRRmo;9E^a*g`I#9xGk^6kn1uJ|ggz4o^5pC*$7baR;CNRvfU5VZ65P}~CKf+W zJoooMCFLNzzmuj%Ak~c|A%Q_%=w%YCm6c?rlS&-pJ#a)8;)T!Fnj3Qd;-Ux$ymf0s zh6ifW!gp6TS~?Sbkp6l(RN~KXwDDOc{3b3TWiZfEb6uh+kp96wxr)!%))PtAW85~G zfd)D8_4)H>zwpY-(_{vGWfns^e)_dz$K+jnyek<%315-VV051qQ}0Kg`}v=es9d^V zvfv1Y-N@*&i70{W_dq&XD9w!yUNQW(R39#b1ml0Qx)jUYl_iNF;aet$rB($?fY7V! z9RaUE{YTPQFXI}}66+wYGE@jg!)I_ZIw17Y@~R9E_e&=T<9fN=+ z83OU560QO9Uv7c0_+Es8)GDD=aKHKa4M=|?Lk&p(Dwu2yl8^7xuB0IhL_Lx)3I$`9 z623ctFa%oanO82o@$Bz?{l&v@NFT!MSSOUD?@4@SyAQpP4>%?BO4}`ynXb z&q|OrGJHTOrZgv*@D9|rN;V|16jGxHP}!MEZiWj4UIqMH3?xN&Mj|%sUY>O z*zN^2kyIl!H37bZtIGhcS;Frr#*rk+?CEP)kALoKU!Ec(fIlCLLplC#V1(~G0~|PX zx+J>xy*yD|U z2z@N)SKu??ya?e1XE1}7h{1`}8UZ-39A(l6tw1eB2A~t#2BQsEOS9#4?fCzG;tNyi zG^TR&`|Trq-x%P)?eOXodEAZS=;#0T-)MwEh`)oWZ}vSKaF+j_f?DSxkxi)Xlnx)H zH>Fyp^Ol6N1mcr2wc!fPM=@mA`Da} z`Q1*O=!F6T2T<1wFbA#Fv;%#NY82_ujX0Awu3v>S7}MWqllYlBe{?kH^~0f4O^_&K zW@=2xJe1j!0!_vig68|7vQs)3;>frLeYvavM7g? z;85Cd`lv-}plTZwT_FQx3=wU_G4TgCa^9UxL+uf$KN7e|)y7|q;0Qt+Aw1MkMiS(a zEaqbRzWw{Q?j0F<@{iBH@fk3|6qw-O%Xj$*<-2%LDvz7_qk91#=A*e_G|&bZM3wBW!&5wTOjVt!Mxi+nH7)$mtNbh|TrV@H zFw5*&{Ck;GSCv@{aXvV zQmDvfs__e%<(Xgn{og-3zq)b%cQZ=(u9yIZc<_+_GoIrYfAz2a*okVb_Bp8iTTP1x zJuefP5bC>>ZD@=rb2vm`$e(2(j5+yK$~&3) zA*$g-+`TdYOJ&|%{~;#9vxUmsd`5<;QDlf>RElo>=)wJ4|Mb%3XPavqzXa#``T6;o zOY#mM?>GaH_`qYH#$5jNGoSqHO}N=`_Oh*E;BOUddQsgcN|;JiQY5Xbn0(Z4o&m{D z4cu0vG*6li_lzxs)vU=hVJK4?4c zK&4i472Pucj9>%OUk2({HpP0wQPPV~Q=1_}`^xg_+@h?<*PqTwTwC3MpHMOlKq3;B zEl28iL`VeHCi|s6IUs$A%PYY5%d7=pLMJlvk`3F)_$|)?OSrr!mrq}o+1D2U3nM~s z8ixaGi>MRnZG9D*q82)0=ED!vxg-{`b-1qDB!wEP;=FoD+`xYFo>~4cD8OCe?7w~a zm7||~_2lEwET297>Ql$%9Xj4I4WP(gCQm_&eeAbEe1aT&KTsefQE$8WNdDl1wjt7G zwVPRC(rf}5dbQ!CadJu}hE64@%RndlDl|Zx6{7{?XW{|$-YdMOMgRuyM#G^D9vqgD zJGV&xz7eTRfEbYas6wd+Q-Ls4_a(d{ysF3!4o%c#>+Vt6eaCj0yk$%s%GHH+i|rl5 zI^R#9HFA<}4x)Mgp(7{HAFNe0ccI3DxePkAVCagPyihe3%|M{0FVMe%M>Gyij334o zA9?lKwa4B`P4JE|fLHq<{)0;VG&#oi&HE(-#Et>3KX?w4EsTjpx(whw@irjaGVG>? za^l_;;_HE2Sv8exYG1lAFr7(AYEUYxlI}po58gH)19uK9(bJkubSWw;Q&q}UsRApA zobREknM4T8p$s6YAxy&XcwG*@Z5?9xu8W^W&sU?**_Ie}4D!gV7JCCg<6+DL!m{Sr(F%|Zp| zAtkMU4~-4V!8>O`ltAK6zzr^&LSCzas|7Lp_lv|K(r1|3o>6p2OQU&;1-UBXEK) zWf1u~1Auv>6UX#y_e1j()NC-k3-a8b#^M{m0a7}RAofD5EyiMj6#Os{9}E)2Qkw!n zry$t_C53;fa>;D8_2nuFUs1-S*R7a@@(&m+wg`eR1B^gC_$g!xWo}Tf1fOC1?k%$C zz*c$l>=jvChL6I0LtyS6lT@C1sujq%4E+d4hh{nyCZ-lhT|9)}qtu8Vi-U_5+c3qK zDbu8l_ix*N>&YvZpIvITerb4c`gpTBvmxK+@f|sV`wtxz1f!E`j!7A*DfqViUSQ3Q)SqS@=+~F zG~`>wyQ4@;_tP28BO7}*I*yHUDh)Dd=)&Zzt3||xxrrJI<%XGm{M;WrzqsDI^VG>> z_sO?;eA^7*GJ4av`Ga5lAOFqkLgKqilDIJ@k)At=NaCl#=9^|f_F7V})WqXE9u{Tp zTonB2s`QO^NAY+I5<{)-dF9%QoNk_x-~7t2$^6m+P`ys>cQ6Jlm#I$8yr=_7RgVc~ z6v3#2=R~UR8UIIiPpEh@1EstS;wvyi#&m#G43kBsW$KxJLSJ9MY}qmn$*;)eGwTTR zMgjEn<2p4k%%Idu!%|mlfDDjH17TpT8s<_>{X(Kr^$(TE005FAiy{fQB1eVHaXz6NaDx<)lp$)v> z#(Q;_QB>zv?7Yl5L5cGVIGdR1BY*#ge)#DB`KAB-5JK?hPrrKX8M(>hrWt^CAH;u@ z#6SL#zjA*oke|g#^&S+?$@H_fR59U6>f&su zeTIG-TBXh-0{!9+%tY2g9FA;Ya}8RfEtc97yKc~RZ-}sYmz-X8k{U7?2T9k-3f9Ei zrce>Y$b!1i#u;jXM`#SAh@JgSrm4{!FqDJj)0yP+)45Hvb(vdvRkjUm2azLj^cH#~ zsWW$+kIXrZEhd`+b)qzFO@`rjBAYz1T7?2SfGbT7HXgnAmc0-E(YZ5Efi^QY3mM-u z1C$W!V=%{``sj~S#vU{H))ce%!WC^RL;?2GU{pRWC0`%Jqjyfe=xCKnrsh-i_Bk!^ z&V$I6eY-2co~(oTe{%Le${(G49!VOLRE@v`BT%VSR%umel>`eT#|YF+2KCax3mkDZ z3=53O$VUt(^*RxWX7cu0naho#YI zfY@dIoafc?vZ%t~=%tk=oYZr;ejEP5RuD79Ger(4vQSScsYJGj2ho%|g>{WkA`6lI zEIWpwS!D(@*7SJXxN~y*%zu9K?AFmO(<3)iOYpXxKuzst@>PT~cm4WDKK>9q`p5id zM)ENKT|MB`KpB#^92&}%_1v!O;hLJ~Igw)xVgM~wrBM*}gm{64LSTSI{`t$lC9}5mZ`PS(SxmQ!Zad3 zNKF$^dR41Il{0ei4j?rOpC{6UQs%B{(oTZ#TrxndUN@%Wb(myYUDc?9naM+=KPrv- zHW}l3MDrxq&P90tnzeVEHJIIv@pxai1%YPslSifmdEf@x|%)_Atp=B_;a?5i(5 zdNbL>w`~G27JB_p{pI-K}^0E5;`ISgM+5-U1+Jy z=$t5@ZPRQcmw2sd_TxMoS5)8VF-rSy=&kSd}~P zyi@+d;rnFo-n}w9Ix3}V)yx>p38J8tvIhn(aQE9I% z%lkfXx6}t4(t>9{H+NN&NtZ8O!gp45;zvgt8Xg8tEssr%%f3DP@LoUe=bTxsF+|v_ zC}Uab1e@Hm&`n~bw9;(J@BKf21ndCJg?qN<- z<`68W9|B_qI%G`!X6F8COif2lGj-}+i?Vo*>^ToUM3}T50)O9)@bN%H;A1Jmr?73s zaD8KhNLC@)moHwBnXi6T7Oq{>`%;a!KvPf!Iwseez}5ck3Ohjeh(i zKc;@hh4UBX>ijjW8k*cXso)Sb2$^&ps{IWxRupC$4h{{E$l&m(RNyz%Lx4#o`YI(Q zl3&S0+`kHjotPSyvtOH2Y#?`SeQAXKPv39TC*WMUNlrCa;59C^XD(vygp5Td)g!l$ zjX(U-+*N9UJ@PG%Z|MY5`thTI81om8eDEiq7S~w81F*i7OKac3h4hr^jM3XAAsNp2 z!j6(kLZm)V7Fe=_i!(b=k+lEi$SQHeO!AP)vlvUT*9Y;%4~|K4OFt4kaF!C&E|fA7 zho~NpmtJ~FUidFxl-V<kKXgzgC$`Gaz@Xk}-+|j?`_7%R zWo!)RGn|cO`;P6<4#QBvWn~Ix?FRa4(oZdb$!G2V9k<^KKVw`bCblSGbpHH#%tfr> zVI7P>#IeGBLaAhtlB;~0edVIeUsyNE&&)iUlpA_#h;*bx<`b3N95^X*KU}8JsRw=< zV?LN8xodn|;|p)T-h4X_;kRUfk+JEgaowN(*MH*|9>86X@J3pc(Mc63@illHP}wC^ z%$qk~z=iFW=yCr#APNgRH8N1#zzFXl;sV`GG>9xBgID^YNokGH^TohZGYMp@igUmS zLcRLxYjX0HSG3B8jHzQtIDwd|`5Vs};+CGD&s_kU3q&d*Bo z!Z}3*2OHzE*jxbf!AT|NFn>{6^C0r_HQav#kS}DgvjL6JksZ5s=mL{=l9?dDcVKFn z<1z*?(1~X0#s4%bYfI~vF9^EMaGE21R+^STNSM!L-9YHlO9~zZT?z62SLoJDadlJ_ zWK;DpI(}wp;TMJmr+?*}Y#(!nta#<52quWKNFBn=R~NZjNoo{EM49uaEDcR2 z$mB2X-goaGym5L404f*YJoZ*J{-zp$(jSNN@NfUbKYRdVI-=PqV&q(5Q%qE3B0ZUW z=k+nPX2q=z&^baRz9Mz*oGdFUdItxqGnm4Awkn`>AdsOCZ--5cb)iP$3P(w7N?jik zHFI;Z7)YuRLiJ|^J zHj5a99Up|lhxmT5Pg<*s5_Oh9;B_ta?(c_v$GvKO15)Z6lrmI2JBu*ns}hI;vo2x` zfBdBvygn2X>;zWm~wvc9y2c_^9I%Oj^iCD{r=47z3=1u=m>=MP90 zikPEdZh>kUsAN>uDU3p74?)~| z4e4SesnpL=4P=CXUuDCS~@*75USbX5`@Qx62^H z($%FES6?uy8f0R}pj@53Dh@3-jV|6AxWYO29tpgT-v@}LBo-|wVi{PSq9&6thPDf# zS&OiNlU6Y&AGu}Uy`Mh|EnrPHp12X6-*R05J%3#P_~(A^*D3i^;)q8luA{bJ6gcBRQno<|(~m$1F#7bZ=rGIpZmz`S-~^&ct4Xi%+MJaah>O8s+^E)Y^!gi$Ez=# zow4#3sb2U5VHo66K(D{e&Kvz;h_SLRqM);-1sa*De?{9Ic5w0HMN8PgF&l(BAE&d2 z+`iQq7!hM!d>*QK0e%6)HBMz8)c*i9!~{SbYKq2kzlLa2s@@j+*y?ayS8a&aSRagwvj=(bpD*qSL9H{#l;oiZ^l@BaMR*PHuqJ#zR)xWEk= z0Gjb3Jmt}+f9BT?gG;BvoK5X88&y&!2=dzf0xqEHE7h>BqiA1Zi!uX?d)0q&)`OUK z=n^RmFT5|2Fe{h9;TsOLL_1j*U8AQ?qa4{_^EHSy*1ugv)w!Nkdl+Svfv9fZGw$?U;(wZhD|1ai z$mdkD&R@AE*XEXF4W_07b8*{k?@@5+>nC56gD?T?DKI)TC@-Hpk849v2KzNMOu#UN zt!V}}VE+*_D6r*ysI1`ss#$RK*?`U|2d@4yKXwUcHj@yQ0h)y|li z3?3M*)}EYiZ9FR0(d?TufY$hB@&JVGks!(*XUP`HLn8UG&Py{1VNwo`Qy4fjH6-2D zJv14%9?yUargkML03c#DgIN$6VB+3qB8T;IgRtYYcO(=gos(o)zLGLP2T371eG6~` zne1WSVGz%^4quqAV;e%lX!MSz25GT6jgq zk>uIEb2|W@Vd=-UmR6SJB@lQ8$l#T$SJk;48`~lSm41m^Ytm^|WOZX*7KfK*w4aV? z4GglTNF=Ypz6A6;IHnfj*fruL>?L5(Pi_hV=@lgJG%;W)CnG%OZrhV=0T!XQ;#~UG-*> zbNz_^QQ{JL~d?`ucUE6U7Rwlxz+m8HYLm%wS}wAAkI!QR^li96`DGlyfqLoN<<4qyqQXau7~VP%S{XLoU*JyZPuKS_%#H+ zI;0CD2jUl_wAdL9T6DD1cPBnMej{h_ItIwt!zPrYkg*5wN5k_ZC6~T{uEE#5eyRlW z<=UZ(2?)n#F5YJ-m+E;A0i*`-snFC`1oDd5i~8_=)w+xf!jor77lkCXG%?e^kuJo56yf(b)>^W-wyKWc2R?WY2-uJW zk--qsyz|X@e7_3Z0O4NAO35g}r6`p@jo0MT>}hF5b$R*Jn^L>7F4KLJ^5)#@GG0q% zYTG1mg+UG18p8uJf>g4oiHXf|_mv|NQyc`!_Q{PZU7)k4sF^S%9?O zufUCG45#^v%ovzza&dn-GR$As>O;EQv4J{4YR+USUkexMQxis} zie|QtQp*=EVyK~86>RnT_OKlwbeGPamip?F3?Uw;eH=nw-eV04st^st{dIjmOvDlx zpoCDbf>3T989L70Uw!be$+pogx?pp#zh5?h?Q0e=wJL;)D^g)Sz|P%!<k%9voDj zr`FSO)$F|ShJi||4ascugR(R)8X?rq0+b)yxre8#8F)(#;MD(#r;j|)X5}p+gRNsD(uR|^b#z2- z+qF~P_}W)x`{cMZBTORviH%m_m6(2R|fnbwED+p%2M0 zvVZT{yALY84GmN`C>&1b7Jy2eAuCMjX6}N(%GznuX$pM3pp!6XUUPUSKX^uqNubR6 z0?yV)nm5RDTCg`l>X@U2pBs3uFDl=EBQwy$095}t>B%H69VWn`@1@=Kd@A{_YQ=1m z)z*bB51^iCW*s&7yOn#3N}$>-J{;cDR&SlOdrg<(3|t{$&i^zY)zIqnGb_qqA!p>` z`Kzy=lC^6WalKI0b-hwn&z~?FlR(rgiWGtYh$=Eg+gk5PC4d9hfM*Wd-I>24m)Dk{ zW#B`wjEe=JkX|kNL>RTa*p!upIUt2K8DVk=_gI;m$M2(3hv&ca#u-`3+K_mLo)cOb zq@-Yug8hbBteVAQu9Bs`$=TFQZTyO4vka$!PXRbOWZL^6u%-t&N=O?*r-H-vCYB&rgelW^{$0amd9k`$5KLtUu z#5hz7B)iPxqd@N@ii^*+Ig@kt)YbQ%5K z-jFjdz98!>D{|({>r#d4u8&V>S~$_{q$Nwa3?XWUXn|UUg(?R7IzI-4-yqO~si~)hY>1l(rFm%Bpn^iNp@i$u0%h@YW?`gn zQCCb2+nmD$@LfFb$9C?WdU4_ER52RJ89-aEBTnQ8**!mcxIl~iCmlJzf-m*zT+5|O zJvf0k8D&@Er8R;0*LCvj9Aku1Pa%Z=J=2vmsvjj@&s?RiV-h@W^XetJeEMZTz~_}v zZ2vL{=dDtTa=1Bl6~GzPH_cFgy{?n#i$!(Kg02xLDOj_PP;oV)#tCvF(6rH+W!X3( zV`lvt0E$@YqiY&<9Ra+1rhd7G(bYC^;;A`W2rGkZkAhefppw`cMAHTc2?K&W&`wzw zDGMC&#bx?@#?X>UV6Kd2AXKnSS;Ear?)ONRYgE=#wJ;Xu2*xUX(>QImR5M!lFaVs; z2XLR~f8&!+P2t8<;+9I~O&khGmbubvNB9n6;xsUV8-(kXle1B-(2|aoGDb-YqwSo) zLCMnf8FUJm1cB;i<7Tez4MVG}QTP-SdF}EgSp%}RxVR+s{y|9R1X8r%b^tBefQ?hl z4jjlNN^~h#71v{$xa3gBa=B`Cee4qi0{PN!Eo33%gn@!gYl!_NG*iWKjpAN|Lv3|# z^?Q+KZjc|~b8+EFN3W3qYHqKuiZ7pI0cyEgaj9VohuL9d4U^xX=_?9R(k->~i)z@b zP^$)+@x#;ghfZi*u}O!37c;duuVY@LRWUQ4fG^df>|T8RNlf7bo&mzH)XJUs>jZ57 zG$GE8Sl=4C0fz6Hz;mpYL5F7B>A|;r9w3tf)}7_0UTr-mwQHn>bENybRtNQ!b&*Nx za0IOu!e>;=A&6K-B8VkeL>pP7*GK4AC9u=Ovm}OBiL~>~=+%K0=yEZqrNq}UvT8Xf z$O-ZMpeT~Z*n_HV%(3EnT*wT2MuufkD_}BYJ z$7k{JoqleLZss)1>I{IN!@L>8E;>#fw=~MKfNB2ox)(W*j*nC6T*}pP=NG?2Dbj_a zm`pm0ahl~l{x)B`JW_)OSl7gi_x^d#+A1725U|!5k*zzntG&MpbWSUaB5Mf~1l?Lh zTYX$sr-;|ev>_AQ#cG)DmX^aShlAK`E`z~3`aaJqLtj<_1t)a9aSfV>=C!K|@oF?f z(?E@)Ha*UZV|dLy2M$W9-fydbD9x#vC1Ul%fngn#*fru4iTPN$*~;fc(IoM0>uF+0 zA0!}Eh-hxwsTJ2GS~6xBiLR0eUC55_tTBUu`8m9GH+{Y79tPlM4EQli`wz2wC%K2} zyd0V{$BAXEnYgmm9HK0|(gKrEPPM$6SiRc5G}i+DjV zR&4+um`65|7=W(`Rz*gsraI<)^bbiDjMsu{zjk&OIsJJd7g?*pNSVv*uoZL+BHXO> z*Ht1-%b25iij7}R!J#oZbLwS`G0@tAa^1?vb&N@%lFU~f3{wK!tX0FI ztDj^M2bgaFB0LD@U!dILvn4S1m@+}Z&Pq4?n$NLgY#xlrk}PtPY|N8Nw_{nR^s+-+ z+NP{BhWdxE7nYLy@Yb==5rVs1%slnLQw24)HR3gG4?XonUM$2P#H)WziU zm)RGfsaU_y-=|J}Q(_~enuA)OGFj-7VtUR7q6e6nhPZ~qMC=F*WkKHWFmdD0oXB@8 ztAl)jEB%Iz%=#N@N0D5t%(p1}MKzhh>MRt2me5GRn}N`MhslDO8bU!Tu(GbfFKeoj z%a7LZxAzQ9ROs9_N?{d|#!>MwvVyAQ#kYbXR8BO%lxfdDMDT5+zHsBF_L%pEl52n@;O z#2_1pP;C)$edsEXR@YWEY|1bXD@Y%&0Onm>T9Sn~&&t({Z%PwHpV+=b`x39OuDIUB z#1LF$Kw^Xyi3gxba81PlL-S$y#2cMZS22ypnVW}H*9f%2OzZj#XDPJ3$Q|!A_Y15J zgK6Q+3POn|P(!LeU~4P6GTXPGS`jCR@SqHK_5mzyxK59mTT({!)Mk?dx6qKXnZywe3t`-;f> z{&6|@-n*o4U|3%K%9kXCgC?QtKj>=~7*)7QwI$w`k6<=YwGcggJlp)rI!wX3G7iC= z3(W;ted%RgGcZ0rrlILJ+`fh+)i^+*g)7(G!csG5Y*Il7axFntGOAiM9J*dVfi;g@ z$Mv}{!33Cf48Fj+wx)v#(D*$wP-qkO;$_69(Ps(+mFkuzyi)U1TxK;Ftjw0g)8Qe0 zu#RWk-q+7aU`prEYXC+7%~sIO?Nev2URyRs$Gi^lc{A&G%wruthPCyB z1BHU1M;8R4_X)DRac0XUlhiqkOx-8WIkbhRnPY%J!$Cw!Q}|?-pfQJAef48gy9V#3Uv1t9Qjhn369Yg9A5m z%di$)D)gJW4It7a2ZB7p!2C7I+N>OgmH@+CX5WBHAd@2lw%S=8JTONb z%H-IjqK=vuaHdBY1<$`Wx2nN(h6rE`qaMIti=1Oj)@oq3T3lD1AniH@Hs@J4@#YZB z%r#j{t+Al>oDo+#UNi%dHv?IN+v=7|$w(yCo=FpqXBFOe(5k3!&}KFccb~gGB|{k z@rVpJ8d^5S67=EWLD%IomD$S|8F=rlAZDx>!<8l?`tq1|5o7gJt7RHf zJ$7m?FnDLJrETN1NfpLC2|r-5#6lUE%qY`d$SxOatA&bKOXgbE2ae9-R#p>XC6l@3 zL7X4@8TH7TUw2m^Wvq@K#_3H6eq&QfSk~A?c~fmcw=of4icLEe6+8Q{_AU$DB8RR+ z*mjN^YXdaz@0=lG?!3CDn8kJI<~M7&)@Th0lD2XoJ?z-EWAUm#2#TJuNdYIH89^3< z4kPW_oVx-|Rncx;Y%8ha*fQEVwv zq>|9GKa?5UiHl0iksFPfp|qu6jDiSq^|`3Q*q~qp$n=p52@8uYIxbUd^6Tmcd<>SP zd2?zt4+VyzPuIYoi}IF-wM_RD&Tz@E^wGRJLK#Y0$F0^0To}lK@T@AiFEG`w593y} zM&burQVwpXR?<8$4trfP6{ss-n2XP(>-adv6UllOrh3?ubp|ZT;60XB)?~PENVMWC zq&?m+kcAshVDhhBo70*AcJS^40crPXW0|6jAiW$H{f8yk`$6~?Tu0bXWDr`U3g>XJ zuOiFqb$R9Wb1KaNoWXX6+yR_yjigwR0`0+)w$LGxDZ<&XZI#L~Ld7*`x~;@L*fcXr zHGR7thz99_3yq61*$oW~o<4yjmuD$CwV!WZA?AFFmcXYv4y4&f@bOvPY>N3CW+E4K zVgt!TzhaF#i#n8W+PEpvT09N$G(@w3R3fwCYCGv@g+7!t9xk~ek&bKq<|~1;JEoY^ zMyDkM{M&XJnv{;8dqBSf2ag;G5sLy6mlF@&5^S20KE(9R`4zbWkY}*3&k8BnWfVRP z7jrDG88hgbK7ck{eZ#c`LDtctlfE?|fY1<{ZG;9|oST=?!K$WY>GiK~q_VuqoFw>YNpJ$aI@BK{Hz~?sIYJZ2p?6yrmT^&?J&fHM7Lch5=IVOtkGOv(-k-) z>IVRzsUv%~Hm}hM$I*|Z4rhNJIRk<()F2CstIAXiyB6jakRBeDTPC)d=k2tWY618p z?e@Ad=NdpJaT=A7a>*@oAIDo4#WVwg2!z6sR451ztk>oB&foD`Fm=ME+9hy_uc+J3 zwxcVt1Kkx}_exAMD>MnZ%+tdFY^~CEwRB~zHOR72?-?}L{b7d(IN`P0b(AYEhcw&4nbt{)J%ZlBiMudJGB zVz4e(;L(%dw8d*6w08Lv2cpok2Lab$lLwK|S#1x=Fc*blY}iD^b|j@Pwit(Bb>km_g*wPtH?1iyu@v%@A`v zi$P48q=#1juane`2K*$uUDcdg_MaA#MD$3R%wd+weO3x>fd|i5P{<`Myfew_92ShR zay4L6=RwOJYEr~4lTA}w5E6zZ_cL-i{zz4H=uMGA*beIDW+3qXwhi_pwl4$TZEE)n z-x-w69eFOnE^8qdYrnrasQPs-dBcRU%STu)nKpyj=mW@98yeOk4{kcW0bhVQge%t; zWpdYk*|qPWmX`U(l*L9)>=(rJ?dsCHFX+}#ux*_(0l=ivN3{=?PbZDqDDm?hNDgUx zCNSq9cIw?pxSH6^Rt$%(l8EVN#a_((QXsAEmcjqMRl$2m-ZNhjYNK~m#f%5H6SbTL@*AizXWt}894#=5*QyJ*WE!_Gr;Q;9lU(`vh3WtP2M|wcb<~XOV{&E zWS|v8G&jrhYi8}7_-HH4OiLe;9?ld9(q`F#%lD_YzYrsaQs$zv%=>6rF&m#pYrcPi znr=6@{4TY!Rz{?SO7DR2po0Z*m!@ByN&Cd|E-u?L6K!@SE8+x!2vTqi-> zZ8{V&f8W;G^QOL!P!t&BFj6f60rZ{3QgJAsV=D7&y#4dfOWW_FfKVJjWvysM3MPu( zz9A|5w~xscsNzMaY+i)j!ZV9>o52XXd)QexxpYCk~+tFcsI%Hw~T@n}f_dYVZph_|6rj zuI)y~%6X5xGHeQy&89eXZI(0jpLF|LSB33M^pnh`;{%Hjob^15*EFW2S?a)9E;|G; z4w6ML;gMK>`$Rd^00|;gVZnh=A?JfBCZFX=m&C15^%BAFF$~naxY!nNf%D#34Wyks zxm(zvHBi(Cbo>1gO;dj$wt^8!&9>!C9CmXMOuBShtFj1?#vo9Jb5_2t6+R&F_F*m` z>z9l3i&}=o)O5W*B$->5Wjl3bx{tveh`b2@VHxmm|N6RI12!z?=B zE&;~Ke7?5)3Bw-kM9{|D-sSlvSz1_?5$d+kHnq?`0ZLFX0G;M6Qr|$kgki3#k~qS; zQrlkFEDzf<*Eu9{en99nfCSc`x$Mja&m+w|JYT7)Dk@z#2U5 zd@asgC&5jJ96PI6T4*l1Ht}WcSjw_AhLem2whZ^n zp&jFLXy+DPM5=xJ*mA~gW)=Fv50{9(MoWnv%> zvt|)?v@kOi=YxyCzkxqSaxzEBFK!g0jqefadjl8}7O9=j91KiAMq_b;CgO7YYQt0g zJkAWfv|j&KG32=c=_VH0KG#0Z*WkU@mgeQ97rr2!jaA9Y16tif$navfswu&v z$kj>~x}4_qi0VtFvg^*R^3vDdv_=nP_MohSQc`CvMd%mgOXYM|QapZDad6Az1!nHu zJQwI+klMsW9v*tvF|gZ;;sGLGzId8v&g2Y$b6&)2IxPh!f=wIudDWAKW@i-lckS(T zwW``1_pk~!#L6Y=xCP?i*{&ojS|{QrEVOJ{6sU))$W;`oZS00T_E7m|%ucdwkq9Lv z(msB#%={O*a_%&|=8jET;Tb}$SW0p&qG_wpwq{dP!5Cb73sq!fU`Wf~xNg9@awRe_ z*^u#(5g8b&r~}8wk=phpCIn7DsAgSCOJOcKnQL$B*XzZuE!@cVQK>=`tX^0b@8v2y z?Fc%U5}&uk73W>^B;tLt%!SYU;&w(F>nF$xSj1k0;OkL5$-hR>z75&f1?F!~w(hwb_nhzZFa@s;b z!F4*0Nk{t$i~$*(7#%_`psesV(L*M-Qnv#+nJp{XqL9e7zwOrayCP7n8MFl&K_!&& zLzDU-sYCv##oC(Xgqeslg@yx1f|i?S6Sz>9%X!Ctv!EJNWbWFwE1B_u`5~$mqHrc~ zMZh@&VC;Nzw@q+3Ysx86Frh;!Wvdm&kgV(tZL?(7mbHoILA7;=&IO+H9RTFYyW6fg zf+1MS3F`3q6)+?s)#Lb`6H;kZTr&v^XM!MeCZLOcS*LGm9qSH4^Zr!t&`@|Vo zm3Bjabb$*As>>iYo%n8KA>;Vu2jCi)GJiPadk`(CkhU8lb?*<@<5O z&jbA#m&gckW}-kb?94fCP8%sBcmygh86&9UGy$EHs2@PYog->PS+LR3DjLU*d3~E} zI#IR-ofQye0Mgml->>R-%hp|T%WZc#ho=ipX)D@tIq&VS8%2W9WCX&yy2VS`x_Xni z1Z?b8(WT(59HP|I0SsL+tcJRYUwE3yo~f-eiHJfQ;$&7FtMw3xRq!ThcToq4R6!_O z>a#3r>^f$8&BkT<%nU|u37RsHKEA{6+#-`SD@wmxn3H9>#?3jy9jUuF9OGI1!s6dq z6;%F@q2T^QM;cr<3@CAiwoC~xZht$crtG3wepCLZ#R!2ReVxd1(or0{)hgmZp3rdr z%!qG_AW%&}iQf6a?NS=Dy@lDW%hHyitNe8hr>o`MmIVmO{KgHwc@*RA_x#XbkgqOY zmCowr{Mk!xxwdJ9lK36EHB>7!oKQxLY-cgu=B`YMuh{D0N;wCia$-6auAwM?j*SgV z9ggI}{IaYAC?cG$bK@&|GOGbpD0&Fl$}xB;^Q*3&-|8VbGabOY^(4}|hS>QAEd1m) z^ID7>nb>Maub8cneT1|~+i8Qy`2ZR!ipx!K zT>?I@;{B@L%VGQM%IWMhHI+8P;ysv<(axiyji<^JRarvFxU{&e4Wm;nyA2d0Q~zGlOZf&*WvSu2{7ef*NqA)zGe5S}%i|nDo{A+i)d3vQ zjCfz1yvowC?K`$2RIKaMv!pF?yQAoisG#8XTX*OVT%zVMbq=9jg?>O;m$KO%i5Dc9 z2b2OuU!$*`2VW$QB_-`$`eiY> zj|N=zX=+iSp8E(u+uKm><2@4In*`4^el?D7 z@K9{VM2L0Ej=fS`$Z3z4Dg#eUj>)#|<5C}}=G{>AI>;mj0N=OV(s1r}+Kr;9^}rxi z_A_+pM4ev;?gTF42^>u}zj_#;@Sd7WNuMQ+p+ug!jsdtZgpe@(0K~;7)YWh}vu=~_ z?S1ZUX8Fq}9`qps$w8txaH_|5zAD76j0U#7e=E>GL%~AV_Oe!Wb{dgE*|maaH*fFA zg|60)l3K2moRe459(-&l(brei_Xftd$z4D83E6S`2iTiLm8@i8A&j&F)RMxpjv*># zx5bN3LAyd!CB8*2xlz7$nf^v;wzMW%&#WV*+~|tPEKr*9or{0C9DlF6RX-8 z-oY+>hEF64wAj)ZwzTU@jX36?1iCsaPskC!2%?;@UcxhxP0SFu9b4?Pt1I(V{f9|w zPxpM;4%>;3ZJB-mChg=s6Z=nOLHa+5d$1w~&0&-jQVjCWR;DUl_~C$v(6_+Ol~k4w zQqLbQ$?lKrg*xl#Tp3apsAE>CP?Aj@m)-t<-pKhaV6`J@F4-0>_&A@0Rp$&i{n(EE zGBI^X>-gBwQxj4=PrHZ(x*Uvi8RlqVmbbB?CJNpDLl)1+<`iSBwTa!b_wFBors|g- z3!FL3!#%HeKsjzkE%Z}5Y>ds?h}Bdsf8(0eQtJa41!3;EwIKvcp+#aEIWeD+8Wuol zQFu9XrEx*8Gw4witIHJAB55}J`PW~39;a?SbNbk?T*m-BxWx#F@!{Y2lcUf4_-&s! zjLT1@zUQ3SByk`m#|Q?TbjysgT;iSf(6G?h&wjX4DEzVGhqp`ZmYVhr(gpxzsEsB;IbtM+Sg-N5jujI!|K_Pb@rt?$#df8wRog}DZ}1O=8C=SRfix1HnO1a%6rE)Qw^zd{_v)%+73toQ|+u1|1KD3UEQfhT_8=p@F}&%C_w=B*&X zvkUVxxd!Md2mz>e44~HQ`1P~6=(FJV!x~d(wnCeA=eDO!=61>IhBz9hi#V@UG>icMJWVJ|}0WHDj_2p;_Wg*Ro(-u=?w7?HuonAC?x zwQ;oV;4KPb`EltyyY}+F`c{D+N2HS5PS(oott4)I$B6vppZ`%g^@UgDjTbJ++SMfq z+kq|+VXdI1aBX1#z&FbZIwN6S8UhzBg;pq=OTI%-Q|GglOoJWAuTLSuJX)N$>jFu) zCH&E!x%J+eva}ay+lhZyDSZSrbOnyt7V}(ffLY*I;u?OPgk~Jnmu9M$6U&~z$okz1 z)xYJgNkFKPCWESo@inw_M_Q;@=_R&XND}&dLU0`u6m6paG+&yfYP?%T9oJouU#1!k{$pqXwoiaE+AoCZm$l7Wq%caoOIYJP%zmWL>iSDkJs0sF7x8W^8 zkAOIh{p2eP=kMLD{&`&2EZUm^L<5h3&_}^(hjqaOcc6$}f4a=D|I}%MkWC_-r>U7g zGyWKW)}lyKLwEtSZ`TKRBJD~zwyI8?bqx!8h$*?$I@S7(1Nw+8+Oa@Ar@~{g?gw_Ni}TXu;cgg6%t@7d@pO*D6zbV&NV>O=|31lXNH3w#vMU;j6M{7--LqqqIl&%*ZC7`s~aO6Wop z3;7bqY32Z0UwduFs5+@4gOj1W|A7NCamR?1Y8JmoC6i`?J3j6%N_}^$_5vpdK_Nab z<@J7>oj}hdcFiz{jQO75UCf`u%3zD_I|eqDtPO2h^97a^Vl4xA0@Y<@4hi+BX6)81 zmYmIN+MJZ5DVQX=zMB$Sj$?`>pN!CTKECC@7 z2e4i>Y^I!)!O3^`%ZGpFz0$vxy>|z4Tt3I*-S2*5MH1GRRQX*&ygKbkFqOJ^evxUq zeFMUtdlebU;|cz#xDBFbuxmz4-9}gw9(Nbm?!-HPd6g<4H-c9 zmdT{SeP)pEd!o}xo4!X7LpW3amIO+J%mEdd^{7**GLr*;Zb}aR$WCMpVY}ctYgKCj zlD*!3hk4ky+4dLn>y{x5^F4Vtzq}@}@7n}-6GGy)mkk`qmFCQ3nLDwy2B8(ItgNou z&Le>>ZBxP-ENTc|YQ?Up@2X0{)CDi1+0V^UiHJ8HsWWkD&$!dHkoGQF;)okej5PY> zFaPB`fEGXNWu{(d(xyi8`&uX&_1Iu9slI}k2X_nK zwrxVs=kji!5Aoi6=1@4_vml3p3(vBd0g7g!>x%?E-%XP1*IRP$#S)?>O8;H=Oi5#+ zB)-JWhu%2^Z13`av%mM+m#E1PpMLGwF}Ya=(01aPJV`C^*ojA)ApDcQ-=5mB%rI-l z_v~I>MLz%TkKZPHKD5u$uDY1ByK9KgtQA9}&4lt2sNtD|V~h6O_x{VYipb^G14FxX zI~L~~DF9fwk3ZK3s-9`OHo2>1Ji~B@k;ZVpY6l;)=i}X!h%sl-rjw?{?|`mb=A^w& zUy&I+L*^KTGjVd;D3DyH*1LHJwG-jlXnd0zCGN@n}cBSq)Mf>W$*Rq{qLKZ zLD8}-b4<`1@7pB#GBL?FsP1ZnuKKj=cAq5(azwjF>OJ=F86dHWR40vTL1n*Hs4BVn z=)T{*Uh#c9H!WNv>v?vcYAMyL8^Zec;L&Rvn^e& zq!PHLZbdWT3F}P}8QK%J$aGz1mi#$_pvxdEaLw}zE}qYvhA7ul*)cWhoI!t$f_6!= z2N6X+{;j0{TQUF-K!;D@(o@s|NB`iFC)!~+qm2&W7-Z~oe{eu<|HwgI;mh5`FI>E! z3nrz@mV$62)w4suJc8B zlz>dGuWjg_j8+$G7(_WTP4V8lcjcN(`yaVI4v>mI_WNi4>oo2*{jH>5=UCpxfqOiR zF+Rmwfz>d6WSvMBn;;G(a?3qCC9K;5iB8TgkV{~85JhVtGA+4n&k`nGySy2@@3>vdy>#Efz7zW=CSbb z_`goLBXY5_syG+^oMPFVKRn~m5#D~w7O4-qg&$#V)@G5{I?A~J?MT1g>+PJx7?Lq1 z_o9E|^N*ZZ2RO6>qQCFK0}_sD8K@GSizclZqp33Pw$W~xCa6@R-0||@NsnzOfYfT| zWzy6LUBVO-I+AxI^Cm8MbV^%g)X0EmqE1W^XA92N`%bX-do3=HnbEx@)t+{;LMjE0$OBwLl;bv9aVzHGXXCtwXc@+gS`*);@f(>%{3pF;2?T(h{;-wrxFq0fl9G zE%vqFu=twz0H02`pLP2KW|?i<5*M07<^y)|vd%@p!&a%zxw|TI19QSz=&c##5o_VBs+dY#H z(_WI;+z~6^uuxnaj~6##V)yRMwQ6OBua`y=Tze9Q)?JjX*@(Aij;clUuNZ>|xyPQl za;Htspd-G8gqux4nmcmdZ_596s=jD8db^TIp8oARhN)vfKTF*RrTbo&sd^>7mkIp! zbyYP@sBdcH+-@tl!KWDj=@@*cB66g&*j^*Q`;l(dq!dAw}~;6aCwKldLx z^4SL;{Md=*mDQt+(Tg6dIN&D=EuN(rAU9LJ*EGFa&arDU2q#+e@uBVY;}?v0Ok34% zr;`(?$CK{ylI1#&U#C9^dt&hGaQdvbpt7e4Q$bA^WA!3}S2QcVCZIRs>1F86sp9U~ z_`3>|8-M1snrGU?fhh%#dV-RhQs)dnOSefWXOjP-r2r6+&cv}IT)UPXa5dozl z(M=hGe9t`(3i*BoJ;$bqpzB@tI)lzIIB|7&!gZlq;)uMN*?dCCnBMkF7N_BS)KMHq za2-?e@bk8rDT*Pb4_&mxB1yHHh@@2wJF(sb`K@7!*DdB0y7OVbZPpOIU{p7C?ceK; zJGJDKGeP7s)=a`=&iwq({~yOx^`|$d`u%a!48Y^`tH)SZ{%ol#Pe1tJeNA}A4`O`H zqF3%AToRDZpqH+-^))T?X2h_%wr1P3q}IgQO9>}}pYza$RqbwsQH<|zgeQEnBX=IN z?7Ht1eTl9ldLr8Se4ef!(5oqmzxQ4{yUsBzGOwQ}Py8MYwds1@jiYoghS{~nc?Enh zoa1lT>)(8QTMWSC^vPqN<Gk39ORzwzJ<5R-?C56B0rxIKJqFCN2>*)fEhCtCGP zM=o4AkI&aMf1ry-V>1a1f7+@YtT5De!DvfbP{m$-dX>AG5XHlLNAWVNu zzRjZ~-@$>5;e)_~z6z&s@zbCFi6{Q=fBw`XVOV+GPYy#rN(`m9&HZ#70T>xH8pE=- zwyLo4#Y>lD|Ni|}l9gCREt!Spqh7D~dhuBoDYPsjwaq4}=_v{AJ#M4{dhG3{Bh?P) z1rRChMkM}ckr{48@ZNh!&u2bMslEz6{KN zceBmDQB}~5$0Uk5c=P5_P`=Kezb5nZOL#5I!rYSne)`n;bNG7ax-w-GGzu(A#|pLFXV#Djn9lZ3E?u#((=>6#@IB?FN(IdPe zfjpB@QrFx6wnLv~Y9{lU~f9$buoIJ}#n2*|W z@=UjU<4^4$41!VONpMR2{QSIb{i@-kQ-MCo!t-Lc>xL$kTrQvpy+&?N!c0|Y)Kfqr zfwg|gvfe1c2vQ`>=FbW}d3h}m<;>}`2wPLxJ+)K2hizt*?sd8aBSmn?AHG0E_d!I2 z=;3@uYN)wGDp+Y=17(wK~D}!mzhXnB5JA_|)lFfAy1c6UTSt18hD{zjEvtRMUOL2nZCt z_qKhH0quLZqYFv^{Ls!<%5E$5wm$se;Gj+lCvz!p+!PCdEKgZ4jt z*AA~nEkv}CFHNtHzj+jiVt@CBfxQf7pA9#LWc&6BUF7N2w1HqnjKVHn^aFg}-?Wf) zvyN^gHqr#XddyyfN|82O|!w!XU=BFIf-2c=`zaoC22)JFuRV3_B%sSYh>9SlQDRlqlU?*@9EDZbB(0K zJTmeO`?ar~xo#ejD`{W6IDcxR)!~N4TQJgpf+0VSJHF5}X30+C`oD~y7xeESJtQ}A zyyFbOgG}I~1H%bEK9feleb5FoT|7V2NgymdF)^VI7AJ-bz#Ks*j`KXa2Yq;S8NnvJ zm$2C;Y4lM-d;@}B@1b{9b~pL6SxabhsHEG))B`xhSlyr7O(r>p3%lzBi!~AJYwe!- zTU~9Q7!XaT=SRtevk#P>h&c1 z{xbj%Mh7lNeE^!^@kjpd@#Z}ry7MliRgcocXDKa2}7e1Ju04IYeA^5A6H@hu3dX z#h*HP{C9C%TjQT*kMlEeUEXf?_^vSk4>G~2SC8FA(?`IFwFEmRM;^o94?|VW68k3{ zY`uG`R#k)-wE@+4-0^$v1v%{N3pQv!V-E+XT}NH>d_k$xPA3rM-S@{|_{P7*W&2yP0nXdQxP9)zS-!lf_L6ZP&um@PdS!#oQ2aX*1_{Z)$_UC{2 zu062*M~l+3j;x^vfHExy&vYjcj||dD?BtSf(phv2H*15ryxa%L z98W#<8&jof^)XD;LnKJKUX{jh!wN{UUi@5_d$Z?X5aummedDOe?b_|nD=r=L?{%w( z1MwSEc-8E`LoLCVUqMU>CWu2+(+Xa?xqN<)$uF;E7|k$o{5SLqZgf7w!kYnuzHbcR4?N5fmNB!E zmBoyn5nx>(>mTTUh?_bkX>uI{_$B1p0o3&Y@EcKaK`QI&eeHd*HqaBO2=n^u7MG0q zSf32w7oxIGpXX_bxCg3Wl1O--OIX`iAaP&BC=5K@+f35z$yzCX;=u=>lu}g*e*~|i zG>!WYK6Dhnf8wp?h%r7!O6{AS-$ z{O9sc9AWT}PQCK>a{})Q2JnZP1xP-a;GrTT@U!23`g5GPhd`FY{M*}T&kU@g*X9!L z{V*za9qFq1E(4f`u)|M-X_?|$0P;cN!ak~T@9lesl@SZ!Z2A+f8+jA=JrR|nC*OP9 zo)gO483+$NWHaH5$G!s({R4ddDftc#jOX_N3jL#-`OdqF0sP_o16CZ}j{(kPu^c~r zTFcPnH=q?jfx|%zL(j;=YdD4?vnil=!o z3L_O_7ffOytJ#DT%O!Ki`^w2PcinYYbN~J$hn_&!1V|9%$@*)rS*!D>o_@M9DAmK5_y?k>d?yGz zZ5=<%97LWOTu&lyRcAl_t|XG12|Ic{dCvq|58(U>P2i}Lw?0z}OV7t?@=Qr;Gk4v! z$A})vy<;&-t`RNkD^xK-(&`8=;O$NpYZ2A{q%DUw!9BZrNfml zx)aPW1p-b-<>-d3=QcZnJh}xUc0hYHLHt>~HG_M;*y_YH5|@xMpL%S zaWJL3jXF~Rp8?;oE-1p?G~(JUd!|vH`|FV4;G@G(BzHROo!8_B49{~6Z`FtA-F*B& zGC=WADTLH>uLH4m_tWm98TUHN4YC8<7^?{l-UNfp-sn2ww$O!CBjON5Aku&{dS_-k zZBGaGIlHRAh|iy4*X?(+dVf2|4?F|h=*XEO6Rwk=3T#6xHs^1UnD~3@24CYI%1TTw wu>#>|(?AyaJ50iC5`x&TeCIWI@3!Or2X=;ZVu1P7f&c&j07*qoM6N<$f`k*JdjJ3c diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index e98179f5..675a39b8 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -5,6 +5,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:go_router/go_router.dart'; import 'package:path_provider/path_provider.dart'; import 'package:pocketbase/pocketbase.dart'; +import 'package:screenshot/screenshot.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:uae_stat/config/toast_util.dart'; @@ -2134,55 +2135,67 @@ class _ChartScreen1State extends ConsumerState { ), ), SizedBox(width: 5), - Stack( - children: [ - // Image.asset( - // UaeNumbersAssetPath.shareUae, - // color: Colors.white, // Outline color - // width: 24, // Slightly larger - // height: 24, - // ), - // Image.asset( - // UaeNumbersAssetPath.shareUae, - // color: Colors.white, - // width: 24, - // height: 24, - // ), - GestureDetector( - onTap: () async { - try { - final svgAssetPath = 'assets/images/sample.svg'; // Update with your actual path - final directory = await getTemporaryDirectory(); - final file = File('${directory.path}/shared_image.svg'); + GestureDetector( + onTap: () async { + try { + // Define share content + final String shareLink = 'https://fcsc-da580.web.app'; // Your link + final String shareText = 'Check this out!'; + final String svgAssetPath = 'assets/logos/fcsc.png'; // Your SVG asset path - // Load the SVG asset and write to the temp file - final svgData = await DefaultAssetBundle.of(context).loadString(svgAssetPath); - await file.writeAsString(svgData); + // Create a controller to capture the SVG as an image + final screenshotController = ScreenshotController(); - // Share the file - await Share.shareXFiles([XFile(file.path)], text: "Check this out!"); - } catch (e) { - print("Error sharing file: $e"); - } - }, - child: SvgPicture.asset( - UaeNumbersAssetPath.share, - semanticsLabel: 'share', - width: 24, - height: 24, - ), - ) + // Render the SVG off-screen and capture it as PNG + final svgWidget = SvgPicture.asset( + svgAssetPath, + width: 200, // Adjust size as needed + height: 200, + ); + // Capture the SVG as a PNG + final Uint8List? capturedImage = await screenshotController.captureFromWidget( + Material( + child: svgWidget, + ), + ); + if (capturedImage == null) { + throw Exception('Failed to capture SVG as image'); + } - // SvgPicture.asset( - // UaeNumbersAssetPath.share, - // semanticsLabel: 'share', - // width: 24, - // height: 24, - // ), - ], - ) + // Save the captured PNG to a temporary file + final directory = await getTemporaryDirectory(); + final file = File('${directory.path}/shared_image.png'); + await file.writeAsBytes(capturedImage); + + // Share the PNG file with text and link + await Share.shareXFiles( + [XFile(file.path)], + text: '$shareText\n$shareLink', + subject: 'Shared Content', + ); + + // Clean up temporary file + await file.delete(); + } catch (e) { + print("Error sharing file: $e"); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error sharing: $e')), + ); + } + }, + child: Container( + width: 24, + height: 24, + child: Icon( + Icons.share, + color: Colors.white, + size: 24, + semanticLabel: 'Share', + ), + ), + ), ], ), SizedBox( 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 42280b3b..bbc2e6c4 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -544,7 +544,7 @@ class _EditProfileState extends State { ? NetworkImage( _avatarUrl) // Load from URL : AssetImage( - 'assets/edit_profile/profile.png') + 'assets/edit_profile/profile.jpg') as ImageProvider, child: _avatarUrl.isNotEmpty ? FutureBuilder( diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 52ade75c..0811419e 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -14,6 +14,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:uae_stat/config/injector.dart'; import 'package:uae_stat/domain/repos/t_auth_repo.dart'; +import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bottom_bar_asset_icon_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/drawer_asset_icon_path.dart'; @@ -787,7 +788,7 @@ class _BaseScaffoldState extends ConsumerState { ) : Image( image: AssetImage( - 'assets/edit_profile/profile.png', + 'assets/edit_profile/profile.jpg', ), fit: BoxFit.cover, width: double.infinity, @@ -912,7 +913,7 @@ class _BaseScaffoldState extends ConsumerState { leading: Icon(Icons.logout), // title: const Text('Logout'), title: Text(AppLocalizations.of(context)!.logout), - onTap: () => logout(context), + onTap: () => _showLogoutConfirmationDialog(context), ), if (userId == 'guest') ListTile( @@ -1084,3 +1085,85 @@ class _BaseScaffoldState extends ConsumerState { } } } +void _showLogoutConfirmationDialog(context) { + double myheight = MediaQuery.of(context).size.height; + showDialog( + context: context, + barrierDismissible: false, // User must tap a button to dismiss dialog + builder: (context) => AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), // Rounded corners + ), + contentPadding: EdgeInsets.zero, + title: Text( + context.translate('Log Out Confirmation', 'تأكيد تسجيل الخروج'), + textAlign: TextAlign.center, + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + content: Padding( + padding: const EdgeInsets.all(20.0), + child: Text( + context.translate( + 'Are you sure you want to log out?', + 'هل أنت متأكد أنك تريد تسجيل الخروج؟'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 18, + color: Color(0xFF898C81), + ), + ), + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, // Space buttons evenly + children: [ + SizedBox( + width: 120, // Set button width + child: TextButton( + onPressed: () => Navigator.pop(context), + style: TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + side: BorderSide( + color: Color(0xFFAA8E83), // Border color + width: 1, + ), + ), + child: Text( + context.translate('Cancel', 'إلغاء'), + style: TextStyle( + color: Color(0xFFAA8E83), + fontSize: 16, + ), + ), + ), + ), + SizedBox( + width: 120, // Set button width + child: TextButton( + onPressed: () { + Navigator.pop(context); + // Add logout function here + }, + style: TextButton.styleFrom( + backgroundColor: Color(0xFFAA8E83), // Background color + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + ), + child: Text( + context.translate('Log Out', 'تسجيل الخروج'), + style: TextStyle(color: Colors.white, fontSize: 16), + ), + ), + ), + ], + ), + SizedBox(height: 10), // Add spacing below buttons + ], + ), + ); +} + diff --git a/pubspec.lock b/pubspec.lock index 1bdd3452..a90e1d09 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1177,6 +1177,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.28.0" + screenshot: + dependency: "direct main" + description: + name: screenshot + sha256: "63817697a7835e6ce82add4228e15d233b74d42975c143ad8cfe07009fab866b" + url: "https://pub.dev" + source: hosted + version: "3.0.0" sdmx: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index b9904725..b5dfb3ce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: marquee: ^2.2.3 url_launcher: ^6.3.1 path_provider: ^2.1.5 + screenshot: ^3.0.0 # dynamic_layouts: # git: # url: https://github.com/flutter/packages.git