diff --git a/android/app/.cxx/Debug/6q3k463w/arm64-v8a/configure_fingerprint.bin b/android/app/.cxx/Debug/6q3k463w/arm64-v8a/configure_fingerprint.bin index c583f991..746a2cf1 100644 --- a/android/app/.cxx/Debug/6q3k463w/arm64-v8a/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/6q3k463w/arm64-v8a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Loge c aC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ۮ2b +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ۮ2b ` -^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\android_gradle_build.json  2 ۮ2g +^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\android_gradle_build.json  2 ۮ2g e -cC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\android_gradle_build_mini.json  2 ܮ2T +cC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\android_gradle_build_mini.json  2 ܮ2T R -PC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\build.ninja  2 ۮ2X +PC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\build.ninja  2 ۮ2X V -TC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\build.ninja.txt  2] +TC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\build.ninja.txt  2] [ -YC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\build_file_index.txt  2 S ܮ2^ +YC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\build_file_index.txt  2 S ܮ2^ \ -ZC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\compile_commands.json  2b +ZC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\compile_commands.json  2b ` -^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\compile_commands.json.bin  2 h +^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\compile_commands.json.bin  2 h f -dC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\metadata_generation_command.txt  2 +dC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\metadata_generation_command.txt  2  ܮ2[ Y -WC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\prefab_config.json  2  ( ܮ2` +WC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\prefab_config.json  2  ( ܮ2` ^ -\C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\symbol_folder_index.txt  2  S ܮ2W +\C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\arm64-v8a\symbol_folder_index.txt  2  S ܮ2W U -SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  2  2 \ No newline at end of file +SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  2  2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/6q3k463w/armeabi-v7a/configure_fingerprint.bin b/android/app/.cxx/Debug/6q3k463w/armeabi-v7a/configure_fingerprint.bin index e7e2f47f..f939f461 100644 --- a/android/app/.cxx/Debug/6q3k463w/armeabi-v7a/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/6q3k463w/armeabi-v7a/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Logg e cC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ܮ2d +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ܮ2d b -`C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\android_gradle_build.json  2 ܮ2i +`C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\android_gradle_build.json  2 ܮ2i g -eC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\android_gradle_build_mini.json  2 ܮ2V +eC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\android_gradle_build_mini.json  2 ܮ2V T -RC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\build.ninja  2 ܮ2Z +RC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\build.ninja  2 ܮ2Z X -VC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\build.ninja.txt  2_ +VC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\build.ninja.txt  2_ ] -[C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\build_file_index.txt  2 S ܮ2` +[C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\build_file_index.txt  2 S ܮ2` ^ -\C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\compile_commands.json  2d +\C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\compile_commands.json  2d b -`C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\compile_commands.json.bin  2 j +`C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\compile_commands.json.bin  2 j h -fC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\metadata_generation_command.txt  2 +fC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\metadata_generation_command.txt  2  ܮ2] [ -YC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\prefab_config.json  2  ( ܮ2b +YC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\prefab_config.json  2  ( ܮ2b ` -^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\symbol_folder_index.txt  2  U ܮ2W +^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\armeabi-v7a\symbol_folder_index.txt  2  U ܮ2W U -SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  2  2 \ No newline at end of file +SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  2  2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/6q3k463w/x86/configure_fingerprint.bin b/android/app/.cxx/Debug/6q3k463w/x86/configure_fingerprint.bin index 3cf79e99..9d5b882f 100644 --- a/android/app/.cxx/Debug/6q3k463w/x86/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/6q3k463w/x86/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Log_ ] [C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ܮ2\ +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ܮ2\ Z -XC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\android_gradle_build.json  2 ܮ2a +XC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\android_gradle_build.json  2 ܮ2a _ -]C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\android_gradle_build_mini.json  2 ܮ2N +]C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\android_gradle_build_mini.json  2 ܮ2N L -JC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\build.ninja  2 ܮ2R +JC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\build.ninja  2 ܮ2R P -NC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\build.ninja.txt  2W +NC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\build.ninja.txt  2W U -SC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\build_file_index.txt  2 S ܮ2X +SC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\build_file_index.txt  2 S ܮ2X V -TC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\compile_commands.json  2\ +TC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\compile_commands.json  2\ Z -XC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\compile_commands.json.bin  2 b +XC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\compile_commands.json.bin  2 b ` -^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\metadata_generation_command.txt  2 +^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\metadata_generation_command.txt  2  ܮ2U S -QC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\prefab_config.json  2  ( ܮ2Z +QC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\prefab_config.json  2  ( ܮ2Z X -VC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\symbol_folder_index.txt  2  M ܮ2W +VC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86\symbol_folder_index.txt  2  M ܮ2W U -SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  2  2 \ No newline at end of file +SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  2  2 \ No newline at end of file diff --git a/android/app/.cxx/Debug/6q3k463w/x86_64/configure_fingerprint.bin b/android/app/.cxx/Debug/6q3k463w/x86_64/configure_fingerprint.bin index eebd8322..cb9b8d49 100644 --- a/android/app/.cxx/Debug/6q3k463w/x86_64/configure_fingerprint.bin +++ b/android/app/.cxx/Debug/6q3k463w/x86_64/configure_fingerprint.bin @@ -2,27 +2,27 @@ C/C++ Structured Logb ` ^C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\additional_project_files.txtC A -?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  2  ܮ2_ +?com.android.build.gradle.internal.cxx.io.EncodedFileFingerPrint  崳2  ܮ2_ ] -[C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\android_gradle_build.json  2 ܮ2d +[C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\android_gradle_build.json  崳2 ܮ2d b -`C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\android_gradle_build_mini.json  2 ܮ2Q +`C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\android_gradle_build_mini.json  崳2 ܮ2Q O -MC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\build.ninja  2 ܮ2U +MC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\build.ninja  崳2 ܮ2U S -QC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\build.ninja.txt  2Z +QC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\build.ninja.txt  崳2Z X -VC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\build_file_index.txt  2 S ܮ2[ +VC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\build_file_index.txt  崳2 S ܮ2[ Y -WC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\compile_commands.json  2_ +WC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\compile_commands.json  崳2_ ] -[C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\compile_commands.json.bin  2 e +[C:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\compile_commands.json.bin  鴳2 e c -aC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\metadata_generation_command.txt  2 +aC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\metadata_generation_command.txt  鴳2  ܮ2X V -TC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\prefab_config.json  2  ( ܮ2] +TC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\prefab_config.json  鴳2  ( ܮ2] [ -YC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\symbol_folder_index.txt  2  P ܮ2W +YC:\flutter code\clone\FCSC\android\app\.cxx\Debug\6q3k463w\x86_64\symbol_folder_index.txt  鴳2  P ܮ2W U -SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  2  2 \ No newline at end of file +SC:\flutter\src\flutter\packages\flutter_tools\gradle\src\main\groovy\CMakeLists.txt  鴳2  2 \ No newline at end of file diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index 674dc32a..1f82ca0d 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -298,6 +298,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:go_router/go_router.dart'; import 'package:uae_stat/config/sessionCheckScreen.dart'; +import 'package:uae_stat/domain/entities/session_entity.dart'; +import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/UAE_Numbers/Social/marriages.dart'; import 'package:uae_stat/presentation/Screens/auth_verification/privacy_policy.dart'; import 'package:uae_stat/presentation/Screens/auth_verification/registration.dart'; @@ -365,7 +367,7 @@ final GoRouter router = GoRouter( routes: [ GoRoute( path: '/', - //builder: (context, state) => LoginRoute(), + //builder: (context, state) => MyHomePage(), builder: (context, state) => SessionCheckScreen(), ), @@ -638,4 +640,16 @@ final GoRouter router = GoRouter( builder: (context, state) => Contact(), ), ], + redirect: (context, state) async { + if (state.uri.path == '/SessionCheckScreen' || state.uri.path == '/login') { + return null; + } + + final session = await PAuthRepo().fetchLocallyStored(); + if (session == null || session.freshness == SessionFreshness.expired) { + return '/login'; + } + + return null; + }, ); diff --git a/lib/config/sessionCheckScreen.dart b/lib/config/sessionCheckScreen.dart index c7e4e160..6958d4a9 100644 --- a/lib/config/sessionCheckScreen.dart +++ b/lib/config/sessionCheckScreen.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; +import 'package:uae_stat/domain/entities/session_entity.dart'; +import 'package:url_launcher/url_launcher.dart'; class SessionCheckScreen extends StatefulWidget { @override @@ -10,51 +12,69 @@ class SessionCheckScreen extends StatefulWidget { class _SessionCheckScreenState extends State { final PAuthRepo _authRepo = PAuthRepo(); + String get playStoreUrl => "https://play.google.com/store/apps/details?id=ae.gov.fcsc.frontend"; + @override void initState() { super.initState(); - _checkSession(); + WidgetsBinding.instance.addPostFrameCallback((_) { + _checkSession(); + }); } - /// 🔍 **Check if Shared Intent Path Exists & Validate Login** Future _checkSession() async { - await Future.delayed(const Duration(seconds: 2)); // Optional splash delay - - final session = await _authRepo.fetchLocallyStored(); + await Future.delayed(Duration(seconds: 2)); // Optional splash delay + final SessionEntity? session = await _authRepo.fetchLocallyStored(); final GoRouterState state = GoRouterState.of(context); final String? intendedPath = state.uri.toString().isNotEmpty && state.uri.path != '/' - ? state.uri.toString() + ? state.uri.path // Use just the path (e.g., "/chartS1") : null; - print('🔍 Checking session... Found: $session'); - print('📌 Shared intent path: $intendedPath'); + print('fetchLocallyStored $session'); - // **If the user is NOT logged in** - if (session == null) { - print('🚫 No session found. Redirecting to login.'); - if (mounted) { - context.go('/login', extra: {'intendedPath': intendedPath ?? '/myhomepage'}); + // First if: Check if app data exists (indicating app setup) + if (session != null) { + // Second if: Check if user is logged in (session is valid) + if (session.freshness != SessionFreshness.expired) { + // User is logged in, check for shared intent path + if (intendedPath != null) { + print('navigating to intended path: $intendedPath'); + if (mounted) { + context.go(intendedPath); + } + } else { + print('myhomepage'); + if (mounted) { + context.go('/myhomepage'); // Redirect to home + } + } + } else { + // User is not logged in, redirect to login with intended path if present + print('session expired, redirecting to login'); + if (mounted) { + context.go('/login', extra: intendedPath != null ? {'intendedPath': intendedPath} : null); + } } - return; - } - - // **If user is logged in & there is a shared path, navigate there** - if (intendedPath != null && intendedPath != state.uri.toString()) { - print('🔗 Navigating to shared path after login: $intendedPath'); - if (mounted) context.go(intendedPath); } else { - print('🏠 No shared path or already on shared path. Redirecting to homepage.'); - if (mounted) context.go('/myhomepage'); + // No session data, redirect to Play Store + print('no session data, redirecting to play store'); + if (mounted) { + _redirectToPlayStore(); + } + } + } + + Future _redirectToPlayStore() async { + final Uri url = Uri.parse(playStoreUrl); + + if (await canLaunchUrl(url)) { + await launchUrl(url, mode: LaunchMode.externalApplication); } } @override Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: CircularProgressIndicator(), - ), - ); + return SizedBox.shrink(); } } diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index 8f73b70f..4409f625 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -8,6 +10,7 @@ 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/api_config.dart'; import 'package:uae_stat/config/toast_util.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/uae_numbers_asset_path.dart'; @@ -31,6 +34,8 @@ class ChartScreen1 extends ConsumerStatefulWidget { final String mainTopic; final String title; final String? keyParam; // Nullable String + final String kpi; + final List> filter_data; const ChartScreen1({ Key? key, @@ -39,17 +44,21 @@ class ChartScreen1 extends ConsumerStatefulWidget { required this.mainTopic, required this.title, required this.keyParam, + required this.kpi, + required this.filter_data, }); @override ConsumerState createState() => _ChartScreen1State(); } class _ChartScreen1State extends ConsumerState { - final _pb = PocketBase('https://pb.venbait.in'); + // final _pb = PocketBase('https://pb.venbait.in'); + final _pb = PocketBase(apiUrl); List> selectedFiltersStorage = []; final GlobalKey _scaffoldKey = GlobalKey(); final ApiService apiService = ApiService(); bool isLoading = true; + bool _isSharing = false; List isChartData = []; List nonChartData = []; Map chartScreenData = {}; @@ -67,6 +76,9 @@ class _ChartScreen1State extends ConsumerState { late Color backgroundColor; final ScrollController _scrollController = ScrollController(); int _activeTabIndex = 0; + dynamic tabWiseKpi=[]; + dynamic tabFilteredKpi=[]; + List> formattedFilters=[]; dynamic _tabsData = []; // List> _tabsData = []; @@ -85,11 +97,12 @@ class _ChartScreen1State extends ConsumerState { super.initState(); final String bgColor = widget.bgColor; print(' bgColor $bgColor'); - // fetchChartData(widget.dataSets); checkIfBookmarked(); locale = ref.read(localeProvider) ?? const Locale('en'); - fetchChartData(widget.dataSets, locale?.languageCode ?? 'en').then((_) { - if (_tabsData.isNotEmpty) { + + fetchChartData(widget.dataSets, locale?.languageCode ?? 'en', widget.kpi, widget.filter_data) + .then((_) { + if(_tabsData.isNotEmpty) { // Call onTabSelected for the first tab onTabSelected(_tabsData[0]['id']); } @@ -159,10 +172,7 @@ class _ChartScreen1State extends ConsumerState { SnackBar( content: Text( AppLocalizations.of(context)!.added_to_Bookmark, - style: TextStyle( - color: Color(0xFF2F692C), fontWeight: FontWeight.w600), ), - backgroundColor: Color(0xFFD6E9C6), duration: Duration(seconds: 2), ), ); @@ -173,10 +183,10 @@ class _ChartScreen1State extends ConsumerState { SnackBar( content: Text( AppLocalizations.of(context)!.failed_To_Remove, - style: TextStyle( - color: Color(0xFF544C4C), fontWeight: FontWeight.w600), + // style: TextStyle( + // color: Color(0xFF544C4C), fontWeight: FontWeight.w600), ), - backgroundColor: Color(0xFFEB5F24), + // backgroundColor: Color(0xFFEB5F24), duration: Duration(seconds: 2), ), ); @@ -205,10 +215,7 @@ class _ChartScreen1State extends ConsumerState { SnackBar( content: Text( AppLocalizations.of(context)!.removed_from_Bookmark, - style: TextStyle( - color: Color(0xFF2F692C), fontWeight: FontWeight.w600), ), - backgroundColor: Color(0xFFD6E9C6), duration: Duration(seconds: 2), ), ); @@ -219,10 +226,10 @@ class _ChartScreen1State extends ConsumerState { SnackBar( content: Text( 'Failed to Remove', - style: TextStyle( - color: Color(0xFF544C4C), fontWeight: FontWeight.w600), + // style: TextStyle( + // color: Color(0xFF544C4C), fontWeight: FontWeight.w600), ), - backgroundColor: Color(0xFFEB5F24), + // backgroundColor: Color(0xFFEB5F24), duration: Duration(seconds: 2), ), ); @@ -270,49 +277,55 @@ class _ChartScreen1State extends ConsumerState { ), 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 + 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, + ), + ), ), ), - 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), + ), ), ), - ), - ), - 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), - ), - ), - ), + ], + ) + ], ), ); @@ -357,48 +370,51 @@ class _ChartScreen1State extends ConsumerState { ), 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 + 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 + ), ), - 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, + 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); - addBookmark(); // Close dialog - }, - style: TextButton.styleFrom( - backgroundColor: Color(0xFFAA8E83), // Set background color - foregroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), // Set text color + SizedBox( + width: 100, // Set the desired width + child: TextButton( + onPressed: () { + Navigator.pop(context); + addBookmark(); // 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), + ), ), - ), - child: Text( - context.translate('Yes', 'نعم'), - style: TextStyle(color: Colors.white, fontSize: 16), - ), - ), + ),], ), ], ), @@ -569,7 +585,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -600,7 +616,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } else { @@ -1057,11 +1073,11 @@ class _ChartScreen1State extends ConsumerState { } else { ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -1091,11 +1107,11 @@ class _ChartScreen1State extends ConsumerState { if (locale.languageCode == 'ar') { ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } else { @@ -1202,6 +1218,8 @@ class _ChartScreen1State extends ConsumerState { // } void processChartData(chartsData) { + print("PROCESSING FILTER CHART DATa"); + // Group data by 'kpi' Map>> groupedData = {}; @@ -1228,10 +1246,9 @@ class _ChartScreen1State extends ConsumerState { String formattedKpi = kpi .split('_') // Split by underscore .map((word) => word.isNotEmpty - ? word[0].toUpperCase() + word.substring(1) - : '') // Capitalize + ? word[0].toUpperCase() + word.substring(1) + : '') // Capitalize .join(' '); // Join words with space - return {'id': kpi, 'name': tabHeading, 'order': tabOrder.toString()}; }).toList(); @@ -1244,7 +1261,7 @@ class _ChartScreen1State extends ConsumerState { print('Sorted Tabs: $_tabs'); - print('Grouped Data: $groupedData'); + // print('Grouped Data: $groupedData'); print('Tabs: $_tabs'); setState(() { @@ -1252,8 +1269,13 @@ class _ChartScreen1State extends ConsumerState { }); } - Future fetchChartData(String dataSets, locale) async { - var data = await apiService.fetchChartData(dataSets, locale); + Future fetchChartData(String dataSets, locale, kpi, filter_data ) async { + var data = await apiService.fetchChartData(dataSets, locale,kpi,filter_data); + + tabFilteredKpi = kpi; + print('FETCH KPI- $kpi'); + print('FETCH KFilter- $filter_data'); + if (data.containsKey('filterData')) { var filterData = data['filterData']; @@ -1281,18 +1303,71 @@ class _ChartScreen1State extends ConsumerState { processChartData(chartsData); + onTabSelected(tabFilteredKpi); + print('chartsData :- $chartsData'); print('cardData :- $cardData'); print('chartScreenData :- $chartScreenData'); // print('filterData :- $filterData'); isLoading = false; }); - print('chartsData -$chartsData'); - print('cardData -$cardData'); + // print('chartsData -$chartsData'); + // print('cardData -$cardData'); } void applyFilters(BuildContext context, List filters, List data, List dataCard, List selectedFilters) { + + print('applyFilters called'); + print('Selected ApplyFilters: $selectedFilters'); + + if (selectedFilters.every((filter) => filter['filter_data'].isEmpty)) { + setState(() { + chartsData = + List.from(originalTabChartsData); // Restore the original data + // cardData = List.from(originalTabCardData); // Restore the original data + }); + print('Returning as no filters are selected'); + Navigator.pop(context); + return; // Exit early since all filter_data are empty + } + + // Transform the selectedFilters list into the required format + formattedFilters = selectedFilters + .where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty) + .map((filter){ + return{ + 'filter_key': filter['filter_key'], + 'filter_data':filter['filter_data'].map((item)=> item.toString()).toList() + }; + }).toList(); + + print('Formatted Filters1: $formattedFilters'); + + // Convert to JSON format + String selectedFormatFilters = jsonEncode({ + 'kpi': tabWiseKpi, + 'filter_data': formattedFilters + }); + + print('Formatted Filters2: $selectedFormatFilters'); + + // Call fetchChartData with correct parameters + fetchChartData( + widget.dataSets, + locale.languageCode ?? 'en', + tabWiseKpi, // Ensure you are passing the correct KPI here + formattedFilters // Pass the formatted filter data here + ); + Navigator.pop(context); + + selectedFiltersStorage = List.from(selectedFilters); + print('selectedFiltersStoraged- $selectedFiltersStorage'); + + } + + void applyFilters1(BuildContext context, List filters, List data, + List dataCard, List selectedFilters) { print("applyFilters called"); print("Selected ApplyFilters: $selectedFilters"); print("Selected data: $data"); @@ -1348,8 +1423,8 @@ class _ChartScreen1State extends ConsumerState { if (kDebugMode) { print( "Selected year: ${selectedFilters.firstWhere((f) => f['filter_key'] == 'TIME_PERIOD', orElse: () => { - 'filter_data': ['Unknown'] - })['filter_data']} - No data for chart: : $chartHeading"); + 'filter_data': ['Unknown'] + })['filter_data']} - No data for chart: : $chartHeading"); } // Add the complete chart data to the filteredData list @@ -1429,13 +1504,18 @@ class _ChartScreen1State extends ConsumerState { } void showRightSideModal(BuildContext context, List filters, List data) { + + print('selectedFiltersStoraged1- $selectedFiltersStorage'); + // Initialize selected filters structure from the stored value, if exists List> selectedFilters = - selectedFiltersStorage.isNotEmpty - ? List.from(selectedFiltersStorage) // Use stored filters - : filters.map((filter) { - return {"filter_key": filter["filter_key"], "filter_data": []}; - }).toList(); // Or initialize empty filters + selectedFiltersStorage.isNotEmpty + ? List.from(selectedFiltersStorage) // Use stored filters + : filters.map((filter) { + return {"filter_key": filter["filter_key"], "filter_data": []}; + }).toList(); // Or initialize empty filters + + print('selectedFiltersStoragedrgt- $selectedFiltersStorage'); showModalBottomSheet( context: context, @@ -1459,11 +1539,12 @@ class _ChartScreen1State extends ConsumerState { children: [ Row( children: [ - Image.asset( - UaeNumbersAssetPath.filterUae, - color: Color(0xFF8E8E8E), // Outline color - width: 24, // Slightly larger - height: 24, + SvgPicture.asset( + UaeNumbersAssetPath.filterCharts, + semanticsLabel: 'Filter', + colorFilter:ColorFilter.mode(Color(0xFF8E8E8E),BlendMode.srcIn), + width: 25, + height: 25, ), SizedBox(width: 8), Text( @@ -1502,7 +1583,7 @@ class _ChartScreen1State extends ConsumerState { final filterKey = filter["filter_key"]; final filterData = filter["filter_data"]; final filter_text_and_order = - filter["filter_text_and_order"]; + filter["filter_text_and_order"]; final fieldOrder = filter_text_and_order['order']; return StatefulBuilder( @@ -1536,11 +1617,11 @@ class _ChartScreen1State extends ConsumerState { return StatefulBuilder( builder: (context, dialogSetState) { final locale = - ref.watch(localeProvider); + ref.watch(localeProvider); print('localelocale $locale'); return AlertDialog( title: Text( - // "${locale == 'ar' ? 'يختار ' : 'Select '}" + // "${locale == 'ar' ? 'يختار ' : 'Select '}" "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}"), content: SingleChildScrollView( child: ListBody( @@ -1550,7 +1631,7 @@ class _ChartScreen1State extends ConsumerState { title: Text( value.toString()), value: selectedFilter[ - "filter_data"] + "filter_data"] .contains(value), onChanged: (bool? isChecked) { @@ -1558,11 +1639,11 @@ class _ChartScreen1State extends ConsumerState { if (isChecked == true) { selectedFilter[ - "filter_data"] + "filter_data"] .add(value); } else { selectedFilter[ - "filter_data"] + "filter_data"] .remove(value); } }); @@ -1598,35 +1679,35 @@ class _ChartScreen1State extends ConsumerState { horizontal: 16.0, vertical: 12.0), decoration: BoxDecoration( border: - Border.all(color: Color(0xFF7296BE)), + Border.all(color: Color(0xFF7296BE)), borderRadius: BorderRadius.circular(8.0), ), child: Wrap( spacing: 8.0, runSpacing: 4.0, children: - selectedFilter["filter_data"].isEmpty - ? [ - Text( - // "${locale == 'ar' ? 'يختار ' : 'Select '}" - "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", - style: TextStyle( - color: Colors.grey)) - ] - : selectedFilter["filter_data"] - .map((value) { - return Chip( - label: Text(value), - // backgroundColor: Colors.white, // Default background color - onDeleted: () { - setState(() { - selectedFilter[ - "filter_data"] - .remove(value); - }); - }, - ); - }).toList(), + selectedFilter["filter_data"].isEmpty + ? [ + Text( + // "${locale == 'ar' ? 'يختار ' : 'Select '}" + "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", + style: TextStyle( + color: Colors.grey)) + ] + : selectedFilter["filter_data"] + .map((value) { + return Chip( + label: Text(value), + // backgroundColor: Colors.white, // Default background color + onDeleted: () { + setState(() { + selectedFilter[ + "filter_data"] + .remove(value); + }); + }, + ); + }).toList(), ), ), ), @@ -1706,6 +1787,13 @@ class _ChartScreen1State extends ConsumerState { cardData = List.from(originalTabCardData); }); selectedFiltersStorage.clear(); + formattedFilters = []; + fetchChartData( + widget.dataSets, + locale.languageCode ?? 'en', + tabWiseKpi, // Ensure you are passing the correct KPI here + formattedFilters // Pass the formatted filter data here + ); Navigator.pop(context); }, style: ElevatedButton.styleFrom( @@ -1726,7 +1814,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -1738,6 +1826,7 @@ class _ChartScreen1State extends ConsumerState { onPressed: () { print( "Selected Filters before applying: $selectedFilters"); + setState(() { chartsData = originalTabChartsData; cardData = originalTabCardData; @@ -1745,7 +1834,7 @@ class _ChartScreen1State extends ConsumerState { applyFilters(context, filters, chartsData, cardData, selectedFilters); - selectedFiltersStorage = List.from(selectedFilters); + // selectedFiltersStorage = List.from(selectedFilters); }, style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF92722A), @@ -1768,7 +1857,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -1787,8 +1876,10 @@ class _ChartScreen1State extends ConsumerState { } void onTabSelected(String tabId) { - print('Selected Tab: $tabId'); - selectedFiltersStorage.clear(); + print('Selected Tab on: $tabId'); + tabWiseKpi = tabId; + + // selectedFiltersStorage.clear(); // Filter the filterDataSet filterData = filterDataSet .where((item) => item['key'] == tabId) @@ -1824,7 +1915,8 @@ class _ChartScreen1State extends ConsumerState { } void performActionForTab(String tabId) { - print('Selected Tab: $tabId'); + + print('Selected Tab perform: $tabId'); // Filter the chartsData array based on the tabId tabFilteredChartData = chartsData.where((chart) { @@ -1880,7 +1972,7 @@ class _ChartScreen1State extends ConsumerState { double calculateAspectRatio(int crossAxisCount, List cardData) { // Determine a default aspect ratio based on the most common chart type in the list if (cardData.any((item) => - item['chart_type'] == 'total' || item['chart_type'] == 'average')) { + item['chart_type'] == 'total' || item['chart_type'] == 'average')) { // return crossAxisCount == 1 ? 0.2 : (crossAxisCount > 2 ? 0.9 : 0.7); return crossAxisCount == 2 ? 1.0 : 0.7; // Larger Content // return crossAxisCount == 2 ? 1.5 : 0.9; @@ -1920,21 +2012,27 @@ class _ChartScreen1State extends ConsumerState { final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null // fetchChartData(widget.dataSets, localeCode); - fetchChartData(widget.dataSets, localeCode).then((_) { + + final List> safeFilterData = widget.filter_data ?? []; + final String safeKpi = widget.kpi ?? ''; + fetchChartData(widget.dataSets,localeCode, safeKpi, safeFilterData).then((_) { + print('DEBUG KPI: $safeKpi'); if (_tabsData.isNotEmpty) { // Call onTabSelected for the first tab onTabSelected(_tabsData[0]['id']); } }); + + }); double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; int crossAxisCount = - cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1; + cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1; final color = - Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); + Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); // Color bodyColor = Color( // int.parse( // (chartScreenData['body_color'] ?? '#898C81') @@ -1983,147 +2081,152 @@ class _ChartScreen1State extends ConsumerState { body: isLoading ? Center(child: CircularProgressIndicator()) : Container( - color: color, + color: color, + child: Column( + children: [ + Container( + // height: myheight / 5, + width: double.infinity, + // color: color, + color: Color(int.parse( + (chartScreenData['header_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))), + child: Padding( + padding: EdgeInsets.only( + left: 30, right: 30, top: 8, bottom: 5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + // widget.mainTopic ?? '', + chartScreenData['main_topic'] ?? '', + style: TextStyle( + color: Colors.white, + fontSize: 26, + fontWeight: FontWeight.w400, + fontFamily: 'Roboto'), + ), + Container( + width: mywidth / 7, + height: 1.5, + child: Divider( + thickness: 3, + color: Colors.white, + )), + Text( + // widget.title, + chartScreenData['data_set_tile_heading'] ?? '', + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.w400, + fontFamily: 'Roboto'), + ), + ], + ), + )), + Container( + color: Color(int.parse( + (chartScreenData['header_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))), child: Column( + crossAxisAlignment: CrossAxisAlignment.end, children: [ - Container( - // height: myheight / 5, - width: double.infinity, - // color: color, - color: Color(int.parse( - (chartScreenData['header_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))), - child: Padding( - padding: EdgeInsets.only( - left: 30, right: 30, top: 8, bottom: 5), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - // widget.mainTopic ?? '', - chartScreenData['main_topic'] ?? '', - style: TextStyle( - color: Colors.white, - fontSize: 26, - fontWeight: FontWeight.w400, - fontFamily: 'Roboto'), - ), - Container( - width: mywidth / 7, - height: 1.5, - child: Divider( - thickness: 3, - color: Colors.white, - )), - Text( - // widget.title, - chartScreenData['data_set_tile_heading'] ?? '', - style: TextStyle( - color: Colors.white, - fontSize: 20, - fontWeight: FontWeight.w400, - fontFamily: 'Roboto'), - ), - ], - ), - )), - Container( - color: Color(int.parse( - (chartScreenData['header_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))), - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Row( - key: bookMarkKey, - children: [ - GestureDetector( - onTap: () { - if (isBookmarked) { - showRemoveBookmarkDialog(); - } else { - showAddBookmarkDialog(); - } - }, - child: Container( - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: isBookmarked - ? Colors.white.withAlpha(90) - : null, // Background color - borderRadius: BorderRadius.circular( - 8), // Curved corners + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Row( + key: bookMarkKey, + children: [ + GestureDetector( + onTap: () { + if (isBookmarked) { + showRemoveBookmarkDialog(); + } else { + showAddBookmarkDialog(); + } + }, + child: Container( + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: isBookmarked + ? Colors.white.withAlpha(90) + : null, // Background color + borderRadius: BorderRadius.circular( + 8), // Curved corners + ), + child: Row( + children: [ + isBookmarked + ? Text( + context.translate( + 'Bookmarked', + 'إشارة مرجعية', ), - child: Row( - children: [ - isBookmarked - ? Text( - context.translate( - 'Bookmarked', - 'إشارة مرجعية', - ), - style: TextStyle( - fontSize: 16, - color: Color(int.parse( - (chartScreenData[ - 'body_color'] ?? - '#898C81') - .replaceFirst( - '#', '0xff'))), - ), - ) - : Text( - context.translate( - 'Bookmark', - 'إشارة مرجعية', - ), - style: const TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - SizedBox(width: 5), - - // Text( - // "Bookmark", - // style: const TextStyle( - // fontSize: 16, - // color: Colors.white), - // ), - // const SizedBox(width: 5), - // Image.asset( - // isBookmarked - // ? UaeNumbersAssetPath - // .bookmarksSelectedUae // Filled bookmark image - // : UaeNumbersAssetPath - // .bookmarksUae, // Default bookmark image - // // color: Colors.white, - // width: 24, - // height: 24, - // ), - Icon( - size: 24, - Icons.bookmarks_rounded, - color: isBookmarked - ? Color(int.parse( - (chartScreenData[ - 'body_color'] ?? - '#898C81') - .replaceFirst( - '#', '0xff'))) - : Colors.white, - ), - ], + style: TextStyle( + fontSize: 16, + color: Color(int.parse( + (chartScreenData[ + 'body_color'] ?? + '#898C81') + .replaceFirst( + '#', '0xff'))), + ), + ) + : Text( + context.translate( + 'Bookmark', + 'إشارة مرجعية', + ), + style: const TextStyle( + fontSize: 16, + color: Colors.white, ), ), - ), - ], + SizedBox(width: 5), + + // Text( + // "Bookmark", + // style: const TextStyle( + // fontSize: 16, + // color: Colors.white), + // ), + // const SizedBox(width: 5), + // Image.asset( + // isBookmarked + // ? UaeNumbersAssetPath + // .bookmarksSelectedUae // Filled bookmark image + // : UaeNumbersAssetPath + // .bookmarksUae, // Default bookmark image + // // color: Colors.white, + // width: 24, + // height: 24, + // ), + Icon( + size: 24, + Icons.bookmarks_rounded, + color: isBookmarked + ? Color(int.parse( + (chartScreenData[ + 'body_color'] ?? + '#898C81') + .replaceFirst( + '#', '0xff'))) + : Colors.white, + ), + ], + ), ), - SizedBox(width: 10), - Row( + ), + ], + ), + SizedBox(width: 10), + Row( + children: [ + GestureDetector( + onTap: () => shareCurrentPage(context, _isSharing), + + child: Row( children: [ Text( context.translate( @@ -2136,660 +2239,230 @@ class _ChartScreen1State extends ConsumerState { ), ), SizedBox(width: 5), - GestureDetector( - onTap: () => shareCurrentPage(context), - child: SvgPicture.asset( - UaeNumbersAssetPath.share, - semanticsLabel: 'share', - width: 24, - height: 24, - )), - ], - ), - SizedBox( - width: 10), // Horizontal space between items - Row( - children: [ - GestureDetector( - onTap: () { - showRightSideModal( - context, filterData, chartsData); - }, - child: Row( - children: [ - Text( - context.translate( - 'Filter', - 'فلتر', - ), - style: const TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - SizedBox(width: 10), - Image.asset( - UaeNumbersAssetPath.filterUae, - color: Colors - .white, // Set color to white - width: 21, - height: 21, - ), - ], - ), + SvgPicture.asset( + UaeNumbersAssetPath.share, + semanticsLabel: 'share', + width: 24, + height: 24, ) - // IconButton( - // icon: Icon(Icons.filter_alt_outlined, - // color: Colors.white, size: 24), - // onPressed: () { - // showRightSideModal( - // context, filterData, chartsData); - // }, - // ), - ], - ), - SizedBox(width: 10), - ], - ), - ], - ), - ), - Expanded( - child: Container( - color: Color(int.parse( - (chartScreenData['body_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))), - child: Padding( - padding: const EdgeInsets.all(10.0), - child: ListView( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // Left arrow button - if (_tabsData.length > 1) - _buildArrowButton( - onPressed: _activeTabIndex > 0 - ? _scrollLeft - : null, - icon: Icons.arrow_back_ios_new, - ), - // Tabs with horizontal scroll - if (_tabsData.length > 1) - Expanded( - child: SingleChildScrollView( - controller: _scrollController, - scrollDirection: Axis.horizontal, - child: Row( - children: List.generate( - _tabsData.length, (index) { - return _buildTab( - _tabsData[index], - isActive: - index == _activeTabIndex, - ); - }), - ), - ), - ), - // Right arrow button - if (_tabsData.length > 1) - _buildArrowButton( - onPressed: - _activeTabIndex < _tabsData.length - 1 - ? _scrollRight - : null, - icon: Icons.arrow_forward_ios, - ), - ], - ), - // Expanded( - // child: Center( - // child: Text( - // 'Selected Tab: ${_tabsData.isNotEmpty ? _tabsData[_activeTabIndex] : 'None'}', - // style: const TextStyle(fontSize: 18), - // ), - // ), - // ), - // nonChartData Cards - Padding( - padding: const EdgeInsets.all(3.34), - child: GridView.builder( - key: cardKey, - itemCount: cardData.length, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - // crossAxisCount: cardData.length % 2 == 0 ? 2 : 3, - - crossAxisSpacing: 2, - - mainAxisSpacing: 5, - - childAspectRatio: MediaQuery.of(context) - .size - .width / - (MediaQuery.of(context).size.height / - (cardData.length % 2 == 0 ? 2 : 2)), - ), - - // Sort and filter the cardData - - itemBuilder: (context, index) { - final item = cardData[index]; - print('item item item $item'); - final chart_type = item['chart_type']; - final chart_heading = item['chart_heading']; - final card_full_length = - item['card_full_length']; - print('cardfulllength $card_full_length'); - final response = - item['response'] as List? ?? - []; - final card_logo = item['card_logo']; - final data = - apiService.processNonChartData(item); - print('processNonChartData'); - - double cardHeight = - (chart_type == 'totals' || - chart_type == 'averages') - ? 180.0 - : 130.0; - // double myheight = MediaQuery.of(context).size.height; - // double mywidth = MediaQuery.of(context).size.width; - // final cardWidth = rowItems.length == 1 ? myWidth : (myWidth - 16) / 2.6; - print('find width $cardData'); - final itemdata = cardData[index]; - // bool isOddLength = cardData.length % 2 != 0; - // bool isLastSingleCard = isOddLength && - // index == cardData.length - 1; - // print('isLastSingleCard $isLastSingleCard'); - - if (response.isEmpty) { - return const SizedBox.shrink(); - // return Container( - // color: Colors.redAccent, - // ); - } - if (response.length == 1) { - return Container( - margin: const EdgeInsets.all(10), - width: card_full_length - ? double.infinity - : null, - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(12), - border: Border.all( - color: Color(int.parse( - (chartScreenData[ - 'border_color'] ?? - '#898C81') - .replaceFirst( - '#', '0xff'))), - // Dynamic border color - width: - 1, // Adjust border thickness - ), - ), - child: Card( - margin: const EdgeInsets.all(0), - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(12), - ), - elevation: 2, - child: Container( - height: cardHeight, - padding: const EdgeInsets.only( - left: 16.0, - right: 16.0, - bottom: 1.0, - top: 1.0), - decoration: BoxDecoration( - color: Colors - .white, // Move color inside BoxDecoration - borderRadius: BorderRadius.circular( - 12), // Ensure border radius is applied - ), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Image.network( - card_logo ?? '', - width: 30, - height: 30, - errorBuilder: (context, - error, stackTrace) { - return Icon(Icons.public, - color: - Color(0xFF90B0D5), - size: - 30); // Fallback icon - }, - ), - const SizedBox(height: 1), - MouseRegion( - onEnter: (event) { - // Show tooltip on hover - final overlay = Overlay - .of(context) - .context - .findRenderObject() - as RenderBox; - final entry = - OverlayEntry( - builder: (context) => - Positioned( - left: overlay - .localToGlobal( - Offset.zero) - .dx, - top: overlay - .localToGlobal( - Offset.zero) - .dy, - child: Material( - color: Colors - .transparent, - child: Container( - padding: - EdgeInsets - .all(8), - decoration: - BoxDecoration( - color: Colors - .black87, - borderRadius: - BorderRadius - .circular( - 4), - ), - child: Text( - chart_heading ?? - 'NA', - style: TextStyle( - color: Colors - .white), - ), - ), - ), - ), - ); - Overlay.of(context) - .insert(entry); - Future.delayed( - Duration(seconds: 2), - () => entry.remove()); - }, - child: Text( - chart_heading ?? 'NA', - textAlign: - TextAlign.center, - maxLines: 2, - overflow: TextOverflow - .ellipsis, // Truncate text with '...' - style: TextStyle( - fontSize: 11, - fontWeight: - FontWeight.w400, - color: Colors.black87, - ), - ), - ), - const SizedBox(height: 5), - Text( - RegExp(r'\d').hasMatch( - response[0][ - 'display_value'] ?? - '') - ? '(${response[0]['display_value'] ?? 'NA'})' - : '${response[0]['display_value'] ?? 'NA'}', - style: const TextStyle( - fontSize: 11, - color: Colors.grey, - overflow: TextOverflow - .ellipsis, // Truncate if text overflows - ), - maxLines: - 1, // Limit to one line to prevent overflow - textAlign: TextAlign - .center, // Ensure proper alignment - ), - const SizedBox(height: 1), - Row( - mainAxisAlignment: - MainAxisAlignment - .center, // Center-aligns the row contents - children: [ - Text( - response[0]['value'] ?? - 'NA', - textAlign: TextAlign - .center, // Ensures text is centered - style: TextStyle( - fontSize: 23, - fontWeight: - FontWeight.w800, - color: (response[0][ - 'font_color'] ?? - '') - .isEmpty - ? bodyColor - : _getColorFromHex( - response[0][ - 'font_color']), - ), - ), - const SizedBox( - width: - 4), // Space between text and icon - if (response[0] - ['calculation'] == - 'different') ...[ - if (response[0][ - 'font_color'] == - '#D83731') - const Icon( - Icons - .arrow_downward, - color: Colors.red, - size: 20) - else if (response[0][ - 'font_color'] == - '#11AF22') - const Icon( - Icons - .arrow_upward, - color: - Colors.green, - size: 20), - ], - ], - ) - ], - ), - ), - )); - } else { - return Container( - margin: const EdgeInsets.all(10), - width: card_full_length - ? double.infinity - : null, - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(12), - border: Border.all( - color: Color(int.parse((chartScreenData[ - 'border_color'] ?? - '#898C81') - .replaceFirst('#', - '0xff'))), // Dynamic border color - width: 1, // Adjust border thickness - ), - ), - child: Card( - margin: const EdgeInsets.all(0), - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(12), - ), - elevation: - 0, // Remove shadow to keep only the outli - - child: Container( - height: cardHeight, - padding: const EdgeInsets.all(10.0), - decoration: BoxDecoration( - color: Colors - .white, // Move color inside BoxDecoration - borderRadius: BorderRadius.circular( - 12), // Ensure border radius is applied - ), - child: Column( - mainAxisSize: MainAxisSize - .min, // Adjust card height based on content - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - // const Icon(Icons.public, - // color: Color(0xFF90B0D5), size: 30), - Image.network( - card_logo ?? '', - width: 30, - height: 30, - errorBuilder: (context, error, - stackTrace) { - return Icon(Icons.public, - color: - Color(0xFF90B0D5), - size: - 30); // Fallback icon - }, - ), - const SizedBox(height: 3), - MouseRegion( - onEnter: (event) { - final overlay = - Overlay.of(context); - final entry = OverlayEntry( - builder: (context) => - Positioned( - left: event.position.dx, - top: event.position.dy + - 10, // Adjust tooltip position - child: Material( - color: Colors - .transparent, - child: Container( - padding: - EdgeInsets.all( - 8), - decoration: - BoxDecoration( - color: Colors - .black87, - borderRadius: - BorderRadius - .circular( - 4), - ), - child: Text( - chart_heading ?? - 'NA', - style: TextStyle( - color: Colors - .white, - fontSize: 10), - ), - ), - ), - ), - ); - overlay.insert(entry); - Future.delayed( - Duration(seconds: 2), - () => entry.remove()); - }, - child: SizedBox( - width: double - .infinity, // Ensures it uses available space - child: Text( - chart_heading ?? 'NA', - textAlign: - TextAlign.center, - maxLines: 2, - overflow: TextOverflow - .ellipsis, // Truncate with '...' - style: TextStyle( - fontSize: 11, - fontWeight: - FontWeight.w400, - color: Colors.black87, - ), - ), - ), - ), - const SizedBox(height: 1), - Text( - // '(${response[0]['display_value'] ?? 'NA'})', - - RegExp(r'\d').hasMatch(response[ - 0][ - 'display_value'] ?? - '') - ? '(${response[0]['display_value'] ?? 'NA'})' - : '${response[0]['display_value'] ?? 'NA'}', - - style: const TextStyle( - fontSize: 11, - color: Colors.grey, - overflow: - TextOverflow.ellipsis, - ), - ), - const SizedBox(height: 1), - Text( - response[0]['value'] ?? 'NA', - overflow: TextOverflow - .ellipsis, // Truncate text if it overflows - maxLines: - 1, // Ensures text stays in a single line - style: TextStyle( - fontSize: 23, - fontWeight: FontWeight.w900, - color: (response[0][ - 'font_color'] ?? - '') - .isEmpty - ? bodyColor - : _getColorFromHex( - response[0] - ['font_color']), - ), - ), - SizedBox( - height: - 2, // Height of the divider - child: Divider( - color: Color(0xFFBBBCBD), - thickness: - 1, // Divider line thickness - ), - ), - Text( - response[1]['value'] ?? 'NA', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: (response[1][ - 'font_color'] ?? - '') - .isEmpty - ? const Color( - 0xFFD83731) - : _getColorFromHex( - response[1] - ['font_color']), - ), - textAlign: TextAlign - .center, // Ensure proper alignment - overflow: TextOverflow - .ellipsis, // Truncate if text overflows - ), - Text( - // '(${response[1]['display_value'] ?? 'NA'})', - RegExp(r'\d').hasMatch(response[ - 1][ - 'display_value'] ?? - '') - ? '(${response[1]['display_value'] ?? 'NA'})' - : '${response[1]['display_value'] ?? 'NA'}', - style: const TextStyle( - fontSize: 8, - fontWeight: FontWeight.w500, - color: Colors.grey, - overflow: - TextOverflow.ellipsis, - ), - ), - ], - ), - ), - ), - ); - } - }, - ), - ), - // chartsData Cards - ListView.builder( - itemCount: chartsData.length, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return Card( - margin: const EdgeInsets.all(10), - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: Color( - int.parse( - (chartScreenData[ - 'border_color'] ?? - '#898C81') - .replaceFirst('#', '0xff'), - ), - ), // Border color - width: 1, // Border width - ), - color: Colors.white, - borderRadius: BorderRadius.circular( - 8), // Optional: Rounded corners - ), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - // ConstrainedBox - Container( - height: (chartsData[index] - ['chart_type'] == - 'pie_chart') - ? 500 - : (chartsData[index][ - 'chart_type'] == - 'bar_chart_horizontal') - ? 370 - : 350, - - // child: buildChart(chartsData[index]), - child: ChartWidget( - chartData: - chartsData[index], - bodyColor: bodyColor)) - ], - ), - ), - )); - }, - ), - ], - ), + ],),), + ], ), - ), + SizedBox( + width: 10), // Horizontal space between items + Row( + children: [ + GestureDetector( + onTap: () { + showRightSideModal( + context, filterData, chartsData); + }, + child: Row( + children: [ + Text( + context.translate( + 'Filter', + 'فلتر', + ), + style: const TextStyle( + fontSize: 16, + color: Colors.white, + ), + ), + SizedBox(width: 10), + SvgPicture.asset( + UaeNumbersAssetPath.filterCharts, + semanticsLabel: 'Filter', + width: 24, + height: 24, + ), + ], + ), + ) + // IconButton( + // icon: Icon(Icons.filter_alt_outlined, + // color: Colors.white, size: 24), + // onPressed: () { + // showRightSideModal( + // context, filterData, chartsData); + // }, + // ), + ], + ), + SizedBox(width: 10), + ], ), ], ), ), + Expanded( + child: Container( + color: Color(int.parse( + (chartScreenData['body_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: ListView( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Left arrow button + if (_tabsData.length > 1) + _buildArrowButton( + onPressed: _activeTabIndex > 0 + ? _scrollLeft + : null, + icon: Icons.arrow_back_ios_new, + ), + // Tabs with horizontal scroll + if (_tabsData.length > 1) + Expanded( + child: SingleChildScrollView( + controller: _scrollController, + scrollDirection: Axis.horizontal, + child: Row( + children: List.generate( + _tabsData.length, (index) { + return _buildTab( + _tabsData[index], + isActive: + index == _activeTabIndex, + ); + }), + ), + ), + ), + // Right arrow button + if (_tabsData.length > 1) + _buildArrowButton( + onPressed: + _activeTabIndex < _tabsData.length - 1 + ? _scrollRight + : null, + icon: Icons.arrow_forward_ios, + ), + ], + ), + // Expanded( + // child: Center( + // child: Text( + // 'Selected Tab: ${_tabsData.isNotEmpty ? _tabsData[_activeTabIndex] : 'None'}', + // style: const TextStyle(fontSize: 18), + // ), + // ), + // ), + // nonChartData Cards + Padding( + padding: const EdgeInsets.all(8.0), + child: LayoutBuilder( + builder: (context, constraints) { + List rows = []; + List tempRow = []; + + for (var card in cardData) { + if (card['card_full_length'] == true) { + if (tempRow.isNotEmpty) { + rows.add(Row(children: tempRow)); + tempRow = []; + } + rows.add(Row( + children: [ + Expanded( + child: CardWidget( + card: card, + chartScreenData: + chartScreenData)), + ], + )); + } else { + tempRow.add(Expanded( + child: CardWidget( + card: card, + chartScreenData: + chartScreenData))); + if (tempRow.length == 2) { + rows.add(Row(children: tempRow)); + tempRow = []; + } + } + } + + if (tempRow.isNotEmpty) { + rows.add(Row(children: tempRow)); + } + + return SingleChildScrollView( + child: Column( + children: rows, + ), + ); + }, + ), + ), + ListView.builder( + itemCount: chartsData.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return Card( + margin: const EdgeInsets.all(10), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: Color( + int.parse( + (chartScreenData[ + 'border_color'] ?? + '#898C81') + .replaceFirst('#', '0xff'), + ), + ), // Border color + width: 1, // Border width + ), + color: Colors.white, + borderRadius: BorderRadius.circular( + 8), // Optional: Rounded corners + ), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + // ConstrainedBox + Container( + height: (chartsData[index] + ['chart_type'] == + 'pie_chart') + ? 500 + : (chartsData[index][ + 'chart_type'] == + 'bar_chart_horizontal') + ? 370 + : (chartsData[index]['chart_type'] == 'fl_stacked_bar') + ? 390 + : 350, + + // child: buildChart(chartsData[index]), + child: ChartWidget( + chartData: + chartsData[index], + bodyColor: bodyColor)) + ], + ), + ), + )); + }, + ), + ], + ), + ), + ), + ), + ], + ), + ), ), ); } @@ -2797,7 +2470,7 @@ class _ChartScreen1State extends ConsumerState { Widget _buildArrowButton( {required VoidCallback? onPressed, required IconData icon}) { final color = - Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); + Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); return Container( margin: EdgeInsets.symmetric(horizontal: 5.0), width: 30.0, // Set the width of the circle @@ -2850,14 +2523,16 @@ class _ChartScreen1State extends ConsumerState { } } -Future shareCurrentPage(BuildContext context) async { +Future shareCurrentPage(BuildContext context, bool _isSharing) async { + if (_isSharing) return; // Prevent multiple taps + + _isSharing = true; try { - // Get current route from go_router final String currentRoute = GoRouterState.of(context).uri.toString(); final String baseAppLink = 'https://fcsc-da580.web.app'; final String shareLink = '$baseAppLink$currentRoute'; final String shareText = 'Check this out!'; - final String svgAssetPath = 'assets/logos/fcsc.png'; + final String svgAssetPath = 'assets/backgrounds/share/fcsc.svg'; final screenshotController = ScreenshotController(); final svgWidget = SvgPicture.asset( @@ -2866,7 +2541,7 @@ Future shareCurrentPage(BuildContext context) async { height: 200, ); final Uint8List? capturedImage = - await screenshotController.captureFromWidget( + await screenshotController.captureFromWidget( Material(child: svgWidget), ); @@ -2875,7 +2550,7 @@ Future shareCurrentPage(BuildContext context) async { } final directory = await getTemporaryDirectory(); - final file = File('${directory.path}/shared_image.png'); + final file = File('${directory.path}/share.svg'); await file.writeAsBytes(capturedImage); await Share.shareXFiles( @@ -2890,6 +2565,8 @@ Future shareCurrentPage(BuildContext context) async { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error sharing: $e')), ); + } finally { + _isSharing = false; // Reset flag after sharing completes } } @@ -2901,3 +2578,396 @@ Color _getColorFromHex(String hexColor) { } return Color(int.parse(hexColor, radix: 16)); } + +class CardWidget extends StatelessWidget { + final Map card; + final Map chartScreenData; + + const CardWidget( + {Key? key, required this.card, required this.chartScreenData}) + : super(key: key); + + @override + Widget build(BuildContext context) { + final chart_type = card['chart_type']; + final chart_heading = card['chart_heading']; + final card_full_length = card['card_full_length']; + print('cardfulllength $card_full_length'); + final response = card['response'] as List? ?? []; + final card_logo = card['card_logo']; + double cardHeight = + (chart_type == 'totals' || chart_type == 'averages') ? 180.0 : 130.0; + + final bodyColor = Color( + int.parse( + (chartScreenData['body_color'] ?? '#898C81').replaceFirst('#', '0xff'), + ), + ); + + + if(response.isEmpty) + { + return SizedBox.shrink(); + } + else if (response.length == 1) { + return Container( + margin: const EdgeInsets.all(10), + // width: card_full_length ? double.infinity : null, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Color(int.parse( + (chartScreenData['border_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))), + // Dynamic border color + width: 1, // Adjust border thickness + ), + ), + child: Card( + margin: const EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + elevation: 2, + child: Container( + // height: cardHeight, + height: 160, + padding: const EdgeInsets.only( + left: 16.0, right: 16.0, bottom: 2.0, top: 1.0), + decoration: BoxDecoration( + color: Colors.white, // Move color inside BoxDecoration + borderRadius: BorderRadius.circular( + 12), // Ensure border radius is applied + ), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.network( + card_logo ?? '', + width: 30, + height: 30, + errorBuilder: (context, error, stackTrace) { + return Icon(Icons.public, + color: Color(0xFF90B0D5), size: 30); // Fallback icon + }, + ), + const SizedBox(height: 1), + MouseRegion( + onEnter: (event) { + // Show tooltip on hover + final overlay = Overlay.of(context) + .context + .findRenderObject() as RenderBox; + final entry = OverlayEntry( + builder: (context) => Positioned( + left: overlay.localToGlobal(Offset.zero).dx, + top: overlay.localToGlobal(Offset.zero).dy, + child: Material( + color: Colors.transparent, + child: Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.black87, + borderRadius: BorderRadius.circular(4), + ), + child: Text( + chart_heading ?? 'NA', + style: TextStyle(color: Colors.white), + ), + ), + ), + ), + ); + Overlay.of(context).insert(entry); + Future.delayed( + Duration(seconds: 2), () => entry.remove()); + }, + child: Text( + chart_heading ?? 'NA', + textAlign: TextAlign.center, + maxLines: 2, + overflow: + TextOverflow.ellipsis, // Truncate text with '...' + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w400, + color: Colors.black87, + ), + ), + ), + const SizedBox(height: 5), + Text( + RegExp(r'\d').hasMatch(response[0]['display_value'] ?? '') + ? '(${response[0]['display_value'] ?? 'NA'})' + : '${response[0]['display_value'] ?? 'NA'}', + style: const TextStyle( + fontSize: 11, + color: Colors.grey, + overflow: + TextOverflow.ellipsis, // Truncate if text overflows + ), + maxLines: 1, // Limit to one line to prevent overflow + textAlign: TextAlign.center, // Ensure proper alignment + ), + const SizedBox(height: 1), + Row( + mainAxisAlignment: MainAxisAlignment + .center, // Center-aligns the row contents + children: [ + Text( + response[0]['value'] ?? 'NA', + textAlign: TextAlign.center, // Ensures text is centered + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.w800, + color: (response[0]['font_color'] ?? '').isEmpty + ? bodyColor + : _getColorFromHex(response[0]['font_color']), + ), + ), + const SizedBox(width: 4), // Space between text and icon + if (response[0]['font_color'] != '') ...[ + if (response[0]['font_color'] == '#D83731') + const Icon(Icons.arrow_downward, + color: Colors.red, size: 20) + else if (response[0]['font_color'] == '#11AF22') + const Icon(Icons.arrow_upward, + color: Colors.green, size: 20), + ], + ], + ) + ], + ), + ), + )); + } else { + return Container( + margin: const EdgeInsets.all(10), + // width: card_full_length ? double.infinity : null, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Color(int.parse( + (chartScreenData['border_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))), // Dynamic border color + width: 1, // Adjust border thickness + ), + ), + child: Card( + margin: const EdgeInsets.all(0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + elevation: 0, // Remove shadow to keep only the outli + + child: Container( + height: 160, + padding: const EdgeInsets.all(10.0), + // padding: const EdgeInsets.only( + // left: 10.0, right: 10.0, bottom: 5.0, top: 1.0), + decoration: BoxDecoration( + color: Colors.white, // Move color inside BoxDecoration + borderRadius: + BorderRadius.circular(12), // Ensure border radius is applied + ), + child: Column( + mainAxisSize: MainAxisSize.min, // Adjust card height based on content + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // const Icon(Icons.public, + // color: Color(0xFF90B0D5), size: 30), + Image.network( + card_logo ?? '', + width: 30, + height: 30, + errorBuilder: (context, error, stackTrace) { + return Icon(Icons.public, + color: Color(0xFF90B0D5), size: 30); // Fallback icon + }, + ), + const SizedBox(height: 3), + MouseRegion( + onEnter: (event) { + final overlay = Overlay.of(context); + final entry = OverlayEntry( + builder: (context) => Positioned( + left: event.position.dx, + top: event.position.dy + 10, // Adjust tooltip position + child: Material( + color: Colors.transparent, + child: Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.black87, + borderRadius: BorderRadius.circular(4), + ), + child: Text( + chart_heading ?? 'NA', + style: + TextStyle(color: Colors.white, fontSize: 10), + ), + ), + ), + ), + ); + overlay.insert(entry); + Future.delayed(Duration(seconds: 2), () => entry.remove()); + }, + child: SizedBox( + width: double.infinity, // Ensures it uses available space + child: Text( + chart_heading ?? 'NA', + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, // Truncate with '...' + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w400, + color: Colors.black87, + ), + ), + ), + ), + const SizedBox(height: 1), + Text( + // '(${response[0]['display_value'] ?? 'NA'})', + + RegExp(r'\d').hasMatch(response[0]['display_value'] ?? '') + ? '(${response[0]['display_value'] ?? 'NA'})' + : '${response[0]['display_value'] ?? 'NA'}', + + style: const TextStyle( + fontSize: 11, + color: Colors.grey, + overflow: TextOverflow.ellipsis, + ), + ), + const SizedBox(height: 1), + + + + Row( + mainAxisAlignment: MainAxisAlignment + .center, // Center-aligns the row contents + children: [ + Text( + response[0]['value'] ?? 'NA', + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: TextStyle( + fontSize: 23, + fontWeight: FontWeight.w900, + color: (response[0]['font_color'] ?? '').isEmpty + ? bodyColor + : _getColorFromHex(response[0]['font_color']), + ), + ), + const SizedBox(width: 1), // Space between text and icon + if (response[0]['font_color'] != '') ...[ + if (response[0]['font_color'] == '#D83731') + const Icon(Icons.arrow_downward, + color: Colors.red, size: 20) + else if (response[0]['font_color'] == '#11AF22') + const Icon(Icons.arrow_upward, + color: Colors.green, size: 20), + ], + ], + ), + + + SizedBox( + height: 2, // Height of the divider + width: 100, + child: Divider( + color: Color(0xFFBBBCBD), + thickness: 1, // Divider line thickness + ), + ), + + + + + Row( + mainAxisAlignment: MainAxisAlignment + .center, // Center-aligns the row contents + children: [ + Text( + response[1]['value'] ?? 'NA', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: (response[1]['font_color'] ?? '').isEmpty + ? const Color(0xFFD83731) + : _getColorFromHex(response[1]['font_color']), + ), + textAlign: TextAlign.center, // Ensure proper alignment + overflow: TextOverflow.ellipsis, // Truncate if text overflows + ), + const SizedBox(width: 1), // Space between text and icon + if (response[1]['font_color'] != '') ...[ + if (response[1]['font_color'] == '#D83731') + const Icon(Icons.arrow_downward, + color: Colors.red, size: 20) + else if (response[1]['font_color'] == '#11AF22') + const Icon(Icons.arrow_upward, + color: Colors.green, size: 20), + ], + ], + ), + + + Text( + // '(${response[1]['display_value'] ?? 'NA'})', + RegExp(r'\d').hasMatch(response[1]['display_value'] ?? '') + ? '(${response[1]['display_value'] ?? 'NA'})' + : '${response[1]['display_value'] ?? 'NA'}', + style: const TextStyle( + fontSize: 8, + fontWeight: FontWeight.w500, + color: Colors.grey, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + ), + ); + } + // return Card( + // elevation: 4, + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + // child: Padding( + // padding: const EdgeInsets.all(16.0), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Image.network( + // card['card_logo'], + // height: 50, + // width: 50, + // fit: BoxFit.contain, + // ), + // SizedBox(height: 10), + // Text( + // card['chart_heading'] ?? '', + // style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + // ), + // SizedBox(height: 10), + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: List.generate(card['response'].length, (index) { + // var response = card['response'][index]; + // return Text( + // "${response['display_value']}: ${response['value']}", + // style: TextStyle(fontSize: 14), + // ); + // }), + // ), + // ], + // ), + // ), + // ); + } +} diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index 7ee43de6..63f06aac 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -378,7 +378,9 @@ class LoginRoute extends HookConsumerWidget { // } else { // context.go('/myhomepage'); // } - context.go('/myhomepage'); + final extra = GoRouterState.of(context).extra as Map?; + final String? intendedPath = extra?['intendedPath'] as String?; + context.go(intendedPath ?? '/myhomepage'); } else { print('profile'); if (userId != null && userId.isNotEmpty) { diff --git a/share b/share new file mode 100644 index 00000000..20950f93 --- /dev/null +++ b/share @@ -0,0 +1,277 @@ +commit 74196e1d1a5744180cc20296f7d61f6cde7be8a2 (HEAD -> dev) +Author: Juki-shiba +Date: Mon Mar 3 14:45:06 2025 +0530 + + Saving local changes before pulling + +commit d4ad4852a8c263bd686bec8af5184169267b031f +Merge: ec5a402 bbae4b5 +Author: Juki-shiba +Date: Mon Mar 3 14:45:00 2025 +0530 + + Saving local changes before pulling + +commit ec5a40285dd72f302a8f9598bc139650abe5674c +Author: Juki-shiba +Date: Mon Mar 3 14:26:28 2025 +0530 + + Saving local changes before pulling + +commit bbae4b5789a9992d01223f49fd6628db59a59ae6 (origin/dev) +Author: Kalonkarthik +Date: Fri Feb 28 18:04:45 2025 +0530 + + Contact page created + +commit de820662f75e57ca43a406354d5bc980e0e5dff8 +Author: Kalonkarthik +Date: Fri Feb 28 12:31:34 2025 +0530 + + bookmark message color change + +commit cd1bb0fc8cf7faa7d44977003948f14dd06b734c +Merge: d7a1b5a ca24970 +Author: venbaittech +Date: Fri Feb 28 09:24:03 2025 +0530 + + merge + +commit d7a1b5aa385966d8d6f7f57e00cdf73d079fc6c7 +Author: venbaittech +Date: Fri Feb 28 09:01:52 2025 +0530 + + chart api changes and dev pocketbase url + +commit ca24970c53fd01acc52139cfe059dfcff4445254 +Author: Kalonkarthik +Date: Thu Feb 27 17:33:22 2025 +0530 + + svg icons replaced,validate msg aligned,bookmark haeding added etc + +commit 30db38c60bb34b3c9817e6e016d6d4b3dd8a17cb +Author: Kalonkarthik +Date: Wed Feb 26 15:25:51 2025 +0530 + + all bookmark categorized and arabic validation bug + +commit cfe5b5bf20b8bb8880f7c8acb24fda7d64a3e6fd +Author: venbaittech +Date: Tue Feb 25 18:08:20 2025 +0530 + + bookmark and cards changes done + +commit cd141bfcb4706c194480732561503c6559970146 +Author: venbaittech +Date: Mon Feb 24 18:41:21 2025 +0530 + + UAE number page search functionality added + +commit 9368e08f910976c58f4262fccb1b5ee681b81459 +Merge: f054dd8 0dc95dd +Author: venbaittech +Date: Mon Feb 24 09:07:30 2025 +0530 + + chart screen merged + +commit f054dd83d50f4d53c42c727b4e92efeebd171b5a +Author: venbaittech +Date: Mon Feb 24 09:02:05 2025 +0530 + + chart changes + +commit 0dc95dd63306194fdb1dcd4f82c66b69aea52525 +Author: Kalonkarthik +Date: Fri Feb 21 17:57:08 2025 +0530 + + bookmark categrized + +commit dc3bfbbaaaf1bbff178476f15019162977d11480 +Author: Juki-shiba +Date: Fri Feb 21 15:23:35 2025 +0530 + + bug fix & share cont + +commit a1993712aca4060c5f1c44a4db035bba4d48c198 +Author: venbaittech +Date: Fri Feb 21 09:11:34 2025 +0530 + + chart changes + +commit bdcdf737a88084a6a14df9d0b38dd193e4b9c4f8 +Merge: fc8a247 585d585 +Author: venbaittech +Date: Fri Feb 21 08:57:06 2025 +0530 + + Merge branch 'dev' of github.com:VinistanSS/FCSC into dev + +commit fc8a2479c23e1bf7762ae3b699ca0978e820691b +Author: venbaittech +Date: Fri Feb 21 08:56:58 2025 +0530 + + version code + +commit 585d585608daab3c2550dbc502b1260d397d4f5f +Merge: 95a8032 349c815 +Author: Juki-shiba +Date: Thu Feb 20 18:23:43 2025 +0530 + + Updated UI for logout confirmation popup + +commit 95a803269b8993ebfda61c0f245afa9fb01a88ef +Merge: c879853 a969c4b +Author: Juki-shiba +Date: Thu Feb 20 18:18:40 2025 +0530 + + Updated UI for logout confirmation popup + +commit 349c815f63a4aed87fcd0039b9002d426db045ae +Merge: 704c2d4 a969c4b +Author: Kalonkarthik +Date: Thu Feb 20 18:09:42 2025 +0530 + + merge commit + +commit c87985381618a66d3242a8921a070b82da576d93 +Author: Juki-shiba +Date: Thu Feb 20 18:03:51 2025 +0530 + + drawer change + +commit 704c2d409f830d071c65e4db6f261a7a8104b8f8 +Author: Kalonkarthik +Date: Thu Feb 20 17:53:18 2025 +0530 + + Validation message arabic Translated + +commit a969c4b37e6997a0a6e4e3172a8955077715a432 +Merge: 25eb1a0 84c62a4 +Author: venbaittech +Date: Thu Feb 20 17:51:59 2025 +0530 + + Merge branch 'dev' of github.com:VinistanSS/FCSC into dev + +commit 25eb1a06e9fd12e09b37cda2fbcf45432f7b215e +Author: venbaittech +Date: Thu Feb 20 17:51:51 2025 +0530 + + chart changes done + +commit 7935d944a2ca4217a4bc62c3c94d0a03e9350b5e +Author: Juki-shiba +Date: Wed Feb 19 18:28:24 2025 +0530 + + fig fix + +commit 84c62a4cc7184389d437bb6904381fe01e25935d +Author: Kalonkarthik +Date: Wed Feb 19 18:20:39 2025 +0530 + + User Guide Arabic Translation + +commit 3cc3a9bcbdf8d56d398618ba18c72b25cb8bccbc +Merge: 80fc023 681f3b4 +Author: venbaittech +Date: Tue Feb 18 18:26:38 2025 +0530 + + Merge branch 'dev' of github.com:VinistanSS/FCSC into dev + +commit 80fc023b4aef008cb10cd3f2058e0f5647098bf3 +Author: venbaittech +Date: Tue Feb 18 18:26:12 2025 +0530 + + charts bug fix + +commit 681f3b49efb1509d1f9e7cc10c58633c746ae887 +Author: Kalonkarthik +Date: Tue Feb 18 18:01:54 2025 +0530 + + App Tour Arabic Updated + +commit feca758194785c0ec7298bd7a18cf9237e28b7ec +Merge: d1bcedd 14d52bd +Author: venbaittech +Date: Tue Feb 18 09:40:07 2025 +0530 + + charts and ui changes + +commit d1bcedd4fe7b1136765b1730015b72f1eb259b42 +Author: venbaittech +Date: Tue Feb 18 09:33:59 2025 +0530 + + charts + +commit 14d52bde7590b29707ba49963e0bca5cecddfd90 +Author: Juki-shiba +Date: Mon Feb 17 18:33:43 2025 +0530 + + Bug Fix - Manage User + +commit e25ddaafd1ff712c8cebb46da9f60bcb720188e0 +Merge: 328c236 4917749 +Author: Juki-shiba +Date: Mon Feb 17 18:32:56 2025 +0530 + + Bug Fix - Manage User + +commit 328c236b055a10681fa842e60328b8449bb4d7d0 +Author: Juki-shiba +Date: Mon Feb 17 18:12:57 2025 +0530 + + Bug Fix - Manage User + +commit 0bef09eac04b5e79401113d586bda3f2f9adb9be +Author: Juki-shiba +Date: Mon Feb 17 16:24:54 2025 +0530 + + bug fix + +commit 4917749f653e68a4f632fa82c060e21b7571171f +Author: venbaittech +Date: Sat Feb 15 18:31:52 2025 +0530 + + notification and chart changes done + +commit f4186a876b5b8993483d5a2fe7526cd3d8e88386 +Merge: 140ea24 8e5c0af +Author: venbaittech +Date: Fri Feb 14 18:25:27 2025 +0530 + + Merge branch 'dev' of github.com:VinistanSS/FCSC into dev + +commit 140ea2405a52d484d8416452357ddc3ae53a5c7b +Author: venbaittech +Date: Fri Feb 14 18:25:18 2025 +0530 + + chart and card changes + +commit 8e5c0af26cf373fbf1a5b69381a655d0b91986c5 +Author: Kalonkarthik +Date: Fri Feb 14 17:37:26 2025 +0530 + + create new password fix + +commit 3779e171080b69f1c6d6e227dfabca4e9727d329 +Merge: a90782a 21c4525 +Author: Juki-shiba +Date: Fri Feb 14 17:17:12 2025 +0530 + + drawer update + +commit a90782a48bb2c0985c29c95b8c0060335e71aae5 +Author: Juki-shiba +Date: Fri Feb 14 17:06:35 2025 +0530 + + drawer update + +commit 21c4525db311552356ac3c999f15efbdbb2bb21a +Author: Kalonkarthik +Date: Fri Feb 14 16:14:22 2025 +0530 + + Back button UserGuide,and open project bux fix + +commit dafc089ae9fba86cb7a22d10d3edc3b29246f0f3 +Author: venbaittech +Date: Fri Feb 14 09:30:01 2025 +0530 + + chart bug fix +