diff --git a/android/app/build.gradle b/android/app/build.gradle index 20b03edd..0546a3d1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) { def flutterVersionCode = localProperties.getProperty("flutter.versionCode") if (flutterVersionCode == null) { - flutterVersionCode = "31" + flutterVersionCode = "32" } def flutterVersionName = localProperties.getProperty("flutter.versionName") if (flutterVersionName == null) { - flutterVersionName = "1.0.30" + flutterVersionName = "1.0.31" } def keystorePropertiesFile = rootProject.file("key.properties") diff --git a/lib/config/deeplink_listener.dart b/lib/config/deeplink_listener.dart index 25c945c9..b5656876 100644 --- a/lib/config/deeplink_listener.dart +++ b/lib/config/deeplink_listener.dart @@ -1,7 +1,7 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:app_links/app_links.dart'; +// import 'package:app_links/app_links.dart'; import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/UAE_Numbers/Social/marriages.dart'; import 'package:uae_stat/presentation/routes/auth_routes/login_route.dart'; import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; @@ -30,12 +30,12 @@ class _DeepLinkListenerState extends State { }); // Also listen for app links (Firebase Hosting links) - final appLinks = AppLinks(); - appLinks.uriLinkStream.listen((Uri? uri) { - if (uri != null) { - handleDeepLink(uri); - } - }); + // final appLinks = AppLinks(); + // appLinks.uriLinkStream.listen((Uri? uri) { + // if (uri != null) { + // handleDeepLink(uri); + // } + // }); } void handleDeepLink(Uri uri) { @@ -45,11 +45,14 @@ class _DeepLinkListenerState extends State { final String firstSegment = uri.pathSegments.first; if (firstSegment == 'marriages') { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => Marriages())); + Navigator.of(context) + .push(MaterialPageRoute(builder: (context) => Marriages())); } else if (firstSegment == 'login') { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => LoginRoute())); + Navigator.of(context) + .push(MaterialPageRoute(builder: (context) => LoginRoute())); } else if (firstSegment == 'home') { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => MyHomePage())); + Navigator.of(context) + .push(MaterialPageRoute(builder: (context) => MyHomePage())); } } } @@ -58,4 +61,4 @@ class _DeepLinkListenerState extends State { Widget build(BuildContext context) { return widget.child; } -} \ No newline at end of file +} diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index c61b7624..ea09fd20 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -77,9 +77,9 @@ class _ChartScreen1State extends ConsumerState { late Color backgroundColor; final ScrollController _scrollController = ScrollController(); int _activeTabIndex = 0; - dynamic tabWiseKpi=[]; - dynamic tabFilteredKpi=[]; - List> formattedFilters=[]; + dynamic tabWiseKpi = []; + dynamic tabFilteredKpi = []; + List> formattedFilters = []; dynamic _tabsData = []; dynamic currentTab = []; @@ -104,10 +104,10 @@ class _ChartScreen1State extends ConsumerState { locale = ref.read(localeProvider) ?? const Locale('en'); print('locale-$locale'); - - fetchChartData(widget.dataSets, locale?.languageCode ?? 'en', widget.kpi, widget.filter_data) + fetchChartData(widget.dataSets, locale?.languageCode ?? 'en', widget.kpi, + widget.filter_data) .then((_) { - if(_tabsData.isNotEmpty) { + if (_tabsData.isNotEmpty) { // Call onTabSelected for the first tab onTabSelected(_tabsData[0]['id']); } @@ -319,7 +319,8 @@ class _ChartScreen1State extends ConsumerState { backgroundColor: Color(0xFFAA8E83), // Set background color foregroundColor: Colors.white, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), // Set text color + borderRadius: + BorderRadius.circular(10.0), // Set text color ), ), child: Text( @@ -330,7 +331,6 @@ class _ChartScreen1State extends ConsumerState { ), ], ) - ], ), ); @@ -377,29 +377,30 @@ class _ChartScreen1State extends ConsumerState { 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 + 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( @@ -411,7 +412,8 @@ class _ChartScreen1State extends ConsumerState { backgroundColor: Color(0xFFAA8E83), // Set background color foregroundColor: Colors.white, shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), // Set text color + borderRadius: + BorderRadius.circular(10.0), // Set text color ), ), child: Text( @@ -419,7 +421,8 @@ class _ChartScreen1State extends ConsumerState { style: TextStyle(color: Colors.white, fontSize: 16), ), ), - ),], + ), + ], ), ], ), @@ -590,7 +593,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -621,7 +624,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } else { @@ -1078,11 +1081,11 @@ class _ChartScreen1State extends ConsumerState { } else { ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -1112,11 +1115,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 { @@ -1251,8 +1254,8 @@ 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(); @@ -1274,9 +1277,9 @@ class _ChartScreen1State extends ConsumerState { }); } - Future fetchChartData(String dataSets, locale, kpi, filter_data ) async { - - var data = await apiService.fetchChartData(dataSets, locale ,kpi,filter_data); + 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'); @@ -1284,13 +1287,12 @@ class _ChartScreen1State extends ConsumerState { print('locale1 - $locale'); // print('locale11 - $loacleData'); - - // Store filter_data if it has a value if (filter_data != null && filter_data is List && filter_data.isNotEmpty) { selectedFiltersApi = filter_data.map>((entry) { if (entry is Map) { - return entry.map((key, value) => MapEntry(key.toString(), value)); + return entry.map( + (key, value) => MapEntry(key.toString(), value)); } return {}; }).toList(); @@ -1298,8 +1300,6 @@ class _ChartScreen1State extends ConsumerState { print('FETVCFILTEr: $selectedFiltersApi'); } - - if (data.containsKey('filterData')) { var filterData = data['filterData']; filterDataSet = filterData.entries @@ -1340,7 +1340,6 @@ class _ChartScreen1State extends ConsumerState { void applyFilters(BuildContext context, List filters, List data, List dataCard, List selectedFilters) { - print('applyFilters called'); print('Selected ApplyFilters: $selectedFilters'); @@ -1358,20 +1357,19 @@ class _ChartScreen1State extends ConsumerState { // Transform the selectedFilters list into the required format formattedFilters = selectedFilters // .where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty) - .map((filter){ - return{ + .map((filter) { + return { 'filter_key': filter['filter_key'], - 'filter_data':filter['filter_data'].map((item)=> item.toString()).toList() + '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 - }); + String selectedFormatFilters = + jsonEncode({'kpi': tabWiseKpi, 'filter_data': formattedFilters}); print('Formatted Filters2: $selectedFormatFilters'); final locale = ref.watch(localeProvider)?.languageCode ?? 'en'; @@ -1384,12 +1382,11 @@ class _ChartScreen1State extends ConsumerState { locale, 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, @@ -1449,8 +1446,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 @@ -1530,16 +1527,15 @@ 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'); @@ -1568,7 +1564,8 @@ class _ChartScreen1State extends ConsumerState { SvgPicture.asset( UaeNumbersAssetPath.filterCharts, semanticsLabel: 'Filter', - colorFilter:ColorFilter.mode(Color(0xFF8E8E8E),BlendMode.srcIn), + colorFilter: ColorFilter.mode( + Color(0xFF8E8E8E), BlendMode.srcIn), width: 25, height: 25, ), @@ -1609,7 +1606,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( @@ -1643,12 +1640,12 @@ 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( @@ -1658,7 +1655,7 @@ class _ChartScreen1State extends ConsumerState { title: Text( value.toString()), value: selectedFilter[ - "filter_data"] + "filter_data"] .contains(value), onChanged: (bool? isChecked) { @@ -1666,11 +1663,11 @@ class _ChartScreen1State extends ConsumerState { if (isChecked == true) { selectedFilter[ - "filter_data"] + "filter_data"] .add(value); } else { selectedFilter[ - "filter_data"] + "filter_data"] .remove(value); } }); @@ -1706,35 +1703,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(), ), ), ), @@ -1814,13 +1811,19 @@ class _ChartScreen1State extends ConsumerState { cardData = List.from(originalTabCardData); }); selectedFiltersStorage.clear(); - formattedFilters = []; + formattedFilters = []; + + final locale = + ref.watch(localeProvider)?.languageCode ?? 'en'; + + print('locale22- $locale'); + fetchChartData( widget.dataSets, - locale.languageCode ?? 'en', + locale, tabWiseKpi, // Ensure you are passing the correct KPI here formattedFilters // Pass the formatted filter data here - ); + ); Navigator.pop(context); }, style: ElevatedButton.styleFrom( @@ -1841,7 +1844,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -1884,7 +1887,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -1909,7 +1912,7 @@ class _ChartScreen1State extends ConsumerState { selectedFiltersStorage.clear(); - if (selectedFiltersApi.isNotEmpty && tabWiseKpi== tabFilteredKpi ) { + if (selectedFiltersApi.isNotEmpty && tabWiseKpi == tabFilteredKpi) { selectedFiltersStorage = List.from(selectedFiltersApi); } @@ -1920,13 +1923,22 @@ class _ChartScreen1State extends ConsumerState { .expand((item) => item) .toList(); - print("FilteringDAtss START1d - $filterData"); print('TABId1 - $tabId'); Map monthMap = { - 'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, - 'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12 + 'jan': 1, + 'feb': 2, + 'mar': 3, + 'apr': 4, + 'may': 5, + 'jun': 6, + 'jul': 7, + 'aug': 8, + 'sep': 9, + 'oct': 10, + 'nov': 11, + 'dec': 12 }; for (var item in filterData) { @@ -1941,24 +1953,26 @@ class _ChartScreen1State extends ConsumerState { int yearB = int.parse(bParts[0]); // if (yearA != yearB) return yearA.compareTo(yearB); - if (yearA != yearB) return yearB.compareTo(yearA); // Sort years in descending order + if (yearA != yearB) + return yearB.compareTo(yearA); // Sort years in descending order if (aParts.length == 1) return -1; // Year-only comes first - if (bParts.length == 1) return 1; // Year-only comes first + if (bParts.length == 1) return 1; // Year-only comes first - int monthA = int.tryParse(aParts[1]) ?? monthMap[aParts[1].toLowerCase()] ?? 0; - int monthB = int.tryParse(bParts[1]) ?? monthMap[bParts[1].toLowerCase()] ?? 0; + int monthA = + int.tryParse(aParts[1]) ?? monthMap[aParts[1].toLowerCase()] ?? 0; + int monthB = + int.tryParse(bParts[1]) ?? monthMap[bParts[1].toLowerCase()] ?? 0; - return monthB.compareTo(monthA); // Sort months in descending order within the same year + return monthB.compareTo( + monthA); // Sort months in descending order within the same year // return monthA.compareTo(monthB); }); item['filter_data'] = timePeriods; - } - else if (item['filter_key'] == 'REF_AREA') { + } else if (item['filter_key'] == 'REF_AREA') { continue; - } - else { + } else { // Sort alphabetically for all other cases List otherFilters = List.from(item['filter_data']); otherFilters.sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase())); @@ -1966,8 +1980,6 @@ class _ChartScreen1State extends ConsumerState { } } - - // for (var item in filterData) { // if (item['filter_key'] == 'TIME_PERIOD') { // // Convert the values to integers, sort them, and convert back to strings @@ -1992,7 +2004,6 @@ class _ChartScreen1State extends ConsumerState { } void performActionForTab(String tabId) { - print('Selected Tab perform: $tabId'); // Filter the chartsData array based on the tabId @@ -2049,7 +2060,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; @@ -2086,8 +2097,6 @@ class _ChartScreen1State extends ConsumerState { final locale = ref.watch(localeProvider); final localeNotifier = ref.read(localeProvider.notifier); - - ref.listen(localeProvider, (previous, next) { final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null @@ -2097,9 +2106,11 @@ class _ChartScreen1State extends ConsumerState { currentTab = tabWiseKpi; print('Saving currentTab: $currentTab After locale change'); - final List> safeFilterData = widget.filter_data ?? []; + final List> safeFilterData = + widget.filter_data ?? []; final String safeKpi = widget.kpi ?? ''; - fetchChartData(widget.dataSets,localeCode, safeKpi, safeFilterData).then((_) { + fetchChartData(widget.dataSets, localeCode, safeKpi, safeFilterData) + .then((_) { print('DEBUG KPI: $safeKpi'); print('TAB11: $currentTab'); @@ -2108,24 +2119,22 @@ class _ChartScreen1State extends ConsumerState { // Call onTabSelected for the first tab onTabSelected(currentTab); print('TAB1: $currentTab'); - }else if (_tabsData.isNotEmpty) { + } else if (_tabsData.isNotEmpty) { // Call onTabSelected for the first tab print('TAB2: $_tabsData'); onTabSelected(_tabsData[0]['id']); } }); - - }); double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; mainTopic = chartScreenData['main_topic'] ?? ''; 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') @@ -2140,7 +2149,7 @@ class _ChartScreen1State extends ConsumerState { (chartScreenData['body_color'] ?? '#898C81').replaceFirst('#', '0xff'), ), ); - final chartHeader =chartScreenData['main_topic'] ?? ''; + final chartHeader = chartScreenData['main_topic'] ?? ''; print('ChartScrnBodyColor'); print('chartHeader - $chartHeader'); @@ -2176,393 +2185,400 @@ class _ChartScreen1State extends ConsumerState { body: isLoading ? Center(child: CircularProgressIndicator()) : Container( - 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'] ?? '', - mainTopic, - 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'))), + color: color, 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 - ), - 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, - ), - ], - ), + 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'] ?? '', + mainTopic, + style: TextStyle( + color: Colors.white, + fontSize: 26, + fontWeight: FontWeight.w400, + fontFamily: 'Roboto'), ), - ), - ], - ), - SizedBox(width: 10), - Row( - children: [ - GestureDetector( - onTap: () => shareCurrentPage(context), + 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 + ), + 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), - child: Row( - children: [ - Text( - context.translate( - 'Share', - 'يشارك', + // 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: const TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - SizedBox(width: 5), - 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), - 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), + Row( + children: [ + GestureDetector( + onTap: () => shareCurrentPage(context), + child: Row( + children: [ + Text( + context.translate( + 'Share', + 'يشارك', + ), + style: const TextStyle( + fontSize: 16, + color: Colors.white, + ), + ), + SizedBox(width: 5), + 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), + 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.only( + top: 8.0, left: 1.0, right: 1.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'] == + 'horizontal_rotate') + ? 385 + : (chartsData[index] + [ + 'chart_type'] == + 'fl_stacked_bar') + ? 390 + : 350, + + // child: buildChart(chartsData[index]), + child: ChartWidget( + chartData: + chartsData[index], + bodyColor: bodyColor, + chartHeader: chartHeader), + ) + ], + ), + ), + )); + }, + ), + ], + ), ), - 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.only(top: 8.0,left:1.0,right: 1.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'] == - 'horizontal_rotate') - ? 385 - : (chartsData[index]['chart_type'] == 'fl_stacked_bar') - ? 390 - : 350, - - // child: buildChart(chartsData[index]), - child: ChartWidget( - chartData: - chartsData[index], - bodyColor: bodyColor, - chartHeader:chartHeader),) - ], - ), - ), - )); - }, - ), - ], - ), - ), - ), - ), - ], - ), - ), ), ); } @@ -2570,7 +2586,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 @@ -2639,7 +2655,7 @@ Future shareCurrentPage(BuildContext context) async { height: 200, ); final Uint8List? capturedImage = - await screenshotController.captureFromWidget( + await screenshotController.captureFromWidget( Material(child: svgWidget), ); @@ -2692,20 +2708,18 @@ class CardWidget extends StatelessWidget { final response = card['response'] as List? ?? []; final card_logo = card['card_logo']; double cardHeight = - (chart_type == 'totals' || chart_type == 'averages') ? 180.0 : 130.0; + (chart_type == 'totals' || chart_type == 'averages') ? 180.0 : 130.0; final bodyColor = Color( int.parse( - (chartScreenData['border_color'] ?? '#898C81').replaceFirst('#', '0xff'), + (chartScreenData['border_color'] ?? '#898C81') + .replaceFirst('#', '0xff'), ), ); - - if(response.isEmpty) - { + if (response.isEmpty) { return SizedBox.shrink(); - } - else if (response.length == 1) { + } else if (response.length == 1) { return Container( margin: const EdgeInsets.all(10), // width: card_full_length ? double.infinity : null, @@ -2784,7 +2798,7 @@ class CardWidget extends StatelessWidget { textAlign: TextAlign.center, maxLines: 2, overflow: - TextOverflow.ellipsis, // Truncate text with '...' + TextOverflow.ellipsis, // Truncate text with '...' style: TextStyle( fontSize: 11, fontWeight: FontWeight.w400, @@ -2801,7 +2815,7 @@ class CardWidget extends StatelessWidget { fontSize: 11, color: Colors.grey, overflow: - TextOverflow.ellipsis, // Truncate if text overflows + TextOverflow.ellipsis, // Truncate if text overflows ), maxLines: 1, // Limit to one line to prevent overflow textAlign: TextAlign.center, // Ensure proper alignment @@ -2865,10 +2879,11 @@ class CardWidget extends StatelessWidget { decoration: BoxDecoration( color: Colors.white, // Move color inside BoxDecoration borderRadius: - BorderRadius.circular(12), // Ensure border radius is applied + BorderRadius.circular(12), // Ensure border radius is applied ), child: Column( - mainAxisSize: MainAxisSize.min, // Adjust card height based on content + mainAxisSize: + MainAxisSize.min, // Adjust card height based on content mainAxisAlignment: MainAxisAlignment.center, children: [ // const Icon(Icons.public, @@ -2901,7 +2916,7 @@ class CardWidget extends StatelessWidget { child: Text( chart_heading ?? 'NA', style: - TextStyle(color: Colors.white, fontSize: 10), + TextStyle(color: Colors.white, fontSize: 10), ), ), ), @@ -2969,7 +2984,6 @@ class CardWidget extends StatelessWidget { ], ), - SizedBox( height: 2, // Height of the divider width: 100, @@ -2979,9 +2993,6 @@ class CardWidget extends StatelessWidget { ), ), - - - Row( mainAxisAlignment: MainAxisAlignment .center, // Center-aligns the row contents @@ -2996,7 +3007,8 @@ class CardWidget extends StatelessWidget { : _getColorFromHex(response[1]['font_color']), ), textAlign: TextAlign.center, // Ensure proper alignment - overflow: TextOverflow.ellipsis, // Truncate if text overflows + overflow: + TextOverflow.ellipsis, // Truncate if text overflows ), const SizedBox(width: 1), // Space between text and icon if (response[1]['font_color'] != '') ...[ @@ -3010,7 +3022,6 @@ class CardWidget extends StatelessWidget { ], ), - Text( // '(${response[1]['display_value'] ?? 'NA'})', RegExp(r'\d').hasMatch(response[1]['display_value'] ?? '') @@ -3064,4 +3075,4 @@ class CardWidget extends StatelessWidget { // ), // ); } -} \ No newline at end of file +} diff --git a/pubspec.yaml b/pubspec.yaml index 4912ce92..3e0cc2ad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: uae_stat description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness." publish_to: "none" -version: 1.0.30+31 +version: 1.0.31+32 environment: sdk: ">=3.2.3 <4.0.0"