diff --git a/android/app/build.gradle b/android/app/build.gradle index d5559200..dc30323b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -15,12 +15,12 @@ if (localPropertiesFile.exists()) { def flutterVersionCode = localProperties.getProperty("flutter.versionCode") if (flutterVersionCode == null) { - flutterVersionCode = "16" + flutterVersionCode = "20" } def flutterVersionName = localProperties.getProperty("flutter.versionName") if (flutterVersionName == null) { - flutterVersionName = "1.0.15" + flutterVersionName = "1.0.19" } //def keystorePropertiesFile = rootProject.file("key.properties") diff --git a/lib/l10n/intl_ar.arb b/lib/l10n/intl_ar.arb index 379d7b69..2f586571 100644 --- a/lib/l10n/intl_ar.arb +++ b/lib/l10n/intl_ar.arb @@ -15,6 +15,11 @@ "exit": "خروج", "bookmark_title": "إشارة مرجعية", + "failed_To_Remove": "فشلت الإزالة", + "removed_from_Bookmark": "تمت الإزالة من الإشارة المرجعية", + "added_to_Bookmark":"تمت إضافته إلى الإشارة المرجعية", + "guide_title": "نموذج الملاحظات", + "notification": "إشعار", "guide_title": "نموذج الملاحظات", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index bb3e4604..f6217299 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -16,6 +16,10 @@ "cancel": "Cancel", "exit": "Exit", "bookmark_title": "Bookmark", + "failed_To_Remove": "Failed to Remove", + "removed_from_Bookmark": "Removed from Bookmark", + "added_to_Bookmark": "Added to Bookmark.", + "notification": "Notification", "register_title": "Register", "register_details": "Please enter your details", diff --git a/lib/presentation/Screens/auth_verification/create_new_pw.dart b/lib/presentation/Screens/auth_verification/create_new_pw.dart index 11da8240..47b1c34e 100644 --- a/lib/presentation/Screens/auth_verification/create_new_pw.dart +++ b/lib/presentation/Screens/auth_verification/create_new_pw.dart @@ -188,7 +188,7 @@ class _CreateNewPwState extends ConsumerState { } @override - Widget build(BuildContext contextx) { + Widget build(BuildContext context) { double screenHeight = MediaQuery.of(context).size.height; double screenWidth = MediaQuery.of(context).size.width; final passwordLocale = ref.watch(localeProvider); diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index e8138ca4..99a9e1a0 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -52,6 +52,7 @@ class _ChartScreen1State extends ConsumerState { List tabFilteredChartData = []; List tabFilteredCardData = []; List cardData = []; + List> filteredAndSortedData = []; List originalChartsData = []; List originalCardData = []; List originalTabCardData = []; @@ -61,6 +62,7 @@ class _ChartScreen1State extends ConsumerState { int _activeTabIndex = 0; dynamic _tabsData = []; + // List> _tabsData = []; late List marriageTargets; late List previousMarriageTargets; late TutorialCoachMark tutorialCoachMark; @@ -146,9 +148,9 @@ class _ChartScreen1State extends ConsumerState { // ToastUtil.showSuccessToast("Added to Bookmark."); ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( + SnackBar( content: Text( - 'Added to Bookmark.', + AppLocalizations.of(context)!.added_to_Bookmark, style: TextStyle( color: Color(0xFF2F692C), fontWeight: FontWeight.w600), ), @@ -162,7 +164,7 @@ class _ChartScreen1State extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - 'Failed to Add', + AppLocalizations.of(context)!.failed_To_Remove, style: TextStyle( color: Color(0xFF544C4C), fontWeight: FontWeight.w600), ), @@ -192,9 +194,9 @@ class _ChartScreen1State extends ConsumerState { }); // ToastUtil.showSuccessToast("Removed from Bookmark."); ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( + SnackBar( content: Text( - 'Removed from Bookmark.', + AppLocalizations.of(context)!.removed_from_Bookmark, style: TextStyle( color: Color(0xFF2F692C), fontWeight: FontWeight.w600), ), @@ -1214,12 +1216,15 @@ class _ChartScreen1State extends ConsumerState { // Format 'kpi' values for _tabs with tab_heading List> _tabs = groupedData.entries.map((entry) { String kpi = entry.key; + var firstChart = entry.value.first; // Extract tab_heading from the first chart in the grouped list String tabHeading = entry.value.isNotEmpty ? entry.value.first['tab_heading'] ?? 'Unknown' : 'Unknown'; + int tabOrder = int.tryParse(firstChart['tab_order'] ?? '0') ?? 0; + String formattedKpi = kpi .split('_') // Split by underscore .map((word) => word.isNotEmpty @@ -1227,9 +1232,18 @@ class _ChartScreen1State extends ConsumerState { : '') // Capitalize .join(' '); // Join words with space - return {'id': kpi, 'name': tabHeading}; + return {'id': kpi, 'name': tabHeading, 'order': tabOrder.toString()}; }).toList(); + // Sort tabs by tab_order + _tabs.sort((a, b) { + int orderA = int.tryParse(a['order'] ?? '0') ?? 0; + int orderB = int.tryParse(b['order'] ?? '0') ?? 0; + return orderA.compareTo(orderB); + }); + + print('Sorted Tabs: $_tabs'); + print('Grouped Data: $groupedData'); print('Tabs: $_tabs'); @@ -1287,7 +1301,7 @@ class _ChartScreen1State extends ConsumerState { setState(() { chartsData = List.from(originalTabChartsData); // Restore the original data - cardData = List.from(originalTabCardData); // Restore the original data + // cardData = List.from(originalTabCardData); // Restore the original data }); print('Returning as no filters are selected'); Navigator.pop(context); @@ -1339,47 +1353,47 @@ class _ChartScreen1State extends ConsumerState { } } - List filteredCardData = []; - for (var chart in dataCard) { - Map chartData = Map.from(chart); - // Extract response data for filtering - List response = chartData['response'] ?? []; + // List filteredCardData = []; + // for (var chart in dataCard) { + // Map chartData = Map.from(chart); + // // Extract response data for filtering + // List response = chartData['response'] ?? []; - // Filter the response based on selected filters - var cardFilteredData = response.where((responseItem) { - final obsKey = responseItem['ObsKey']; + // // Filter the response based on selected filters + // var cardFilteredData = response.where((responseItem) { + // final obsKey = responseItem['ObsKey']; - // Check if each selected filter's `filter_data` matches `ObsKey` values - return selectedFilters.every((filter) { - final filterKey = filter['filter_key']; - final filterValues = filter['filter_data']; + // // Check if each selected filter's `filter_data` matches `ObsKey` values + // return selectedFilters.every((filter) { + // final filterKey = filter['filter_key']; + // final filterValues = filter['filter_data']; - // Ensure the filter_key exists in the `ObsKey` and check if it matches any of the `filter_data` - if (obsKey.containsKey(filterKey)) { - final obsKeyValue = obsKey[filterKey]?.toString(); - return filterValues.isEmpty || filterValues.contains(obsKeyValue); - } - return false; - }); - }).toList(); - - // If any data matches the filter, add the whole chart data object - if (cardFilteredData.isNotEmpty) { - filteredCardData.add({ - ...chart, // Include all other properties of the chart object - 'response': cardFilteredData, // Only include filtered response data - }); - } - } + // // Ensure the filter_key exists in the `ObsKey` and check if it matches any of the `filter_data` + // if (obsKey.containsKey(filterKey)) { + // final obsKeyValue = obsKey[filterKey]?.toString(); + // return filterValues.isEmpty || filterValues.contains(obsKeyValue); + // } + // return false; + // }); + // }).toList(); +// + // // If any data matches the filter, add the whole chart data object + // if (cardFilteredData.isNotEmpty) { + // filteredCardData.add({ + // ...chart, // Include all other properties of the chart object + // 'response': cardFilteredData, // Only include filtered response data + // }); + // } + // } // Update the chartsData with the filtered data setState(() { chartsData = filteredData; - cardData = filteredCardData; // Adjust this part as needed + // cardData = filteredCardData; // Adjust this part as needed }); print("Filtered Data: $filteredData"); - print("Filtered Card: $filteredCardData"); + // print("Filtered Card: $filteredCardData"); // Go back after applying filters Navigator.pop(context); @@ -1417,17 +1431,17 @@ class _ChartScreen1State extends ConsumerState { children: [ // Header Section Padding( - padding: const EdgeInsets.only(top:16.0, bottom: 0.0, left: 16.0, right: 16.0), + padding: const EdgeInsets.only( + top: 16.0, bottom: 0.0, left: 16.0, right: 16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ - Image.asset( UaeNumbersAssetPath.filterUae, - color:Color(0xFF8E8E8E), // Outline color - width: 24, // Slightly larger + color: Color(0xFF8E8E8E), // Outline color + width: 24, // Slightly larger height: 24, ), SizedBox(width: 8), @@ -1437,11 +1451,10 @@ class _ChartScreen1State extends ConsumerState { 'المرشحات', ), style: TextStyle( - color: Color(0xFF8E8E8E), + color: Color(0xFF8E8E8E), fontSize: 20, fontWeight: FontWeight.w500, fontFamily: 'Roboto', - ), ), ], @@ -1563,7 +1576,8 @@ class _ChartScreen1State extends ConsumerState { padding: EdgeInsets.symmetric( horizontal: 16.0, vertical: 12.0), decoration: BoxDecoration( - border: Border.all(color: Color(0xFF7296BE)), + border: + Border.all(color: Color(0xFF7296BE)), borderRadius: BorderRadius.circular(8.0), ), child: Wrap( @@ -1726,8 +1740,7 @@ class _ChartScreen1State extends ConsumerState { fit: BoxFit .scaleDown, // Ensures text resizes if necessary child: Text( - context.translate( - 'Filter', 'فلتر'), + context.translate('Filter', 'فلتر'), style: TextStyle( color: Colors.white, fontSize: 13, @@ -1807,8 +1820,14 @@ class _ChartScreen1State extends ConsumerState { return chart['kpi'] == tabId; }).toList(); // Convert to list after filtering - print('tabFilteredCardData Data for Tab $tabId: $tabFilteredCardData'); + print( + 'tabFilteredCardData Data for Tab before $tabId: $tabFilteredCardData'); + tabFilteredCardData + .sort((a, b) => (a['order_id'] as int).compareTo(b['order_id'] as int)); + + print( + 'tabFilteredCardData Data for Tab after $tabId: $tabFilteredCardData'); setState(() { cardData = tabFilteredCardData; originalTabCardData = List.from(tabFilteredCardData); @@ -1839,14 +1858,12 @@ class _ChartScreen1State extends ConsumerState { // 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; - } else { return crossAxisCount == 2 ? 1.5 : 0.9; // Shorter Content } } - // double calculateAspectRatio(int crossAxisCount, List cardData) { // if (cardData.any((item) => // item['chart_type'] == 'total' || item['chart_type'] == 'average')) { @@ -1889,731 +1906,703 @@ class _ChartScreen1State extends ConsumerState { final color = Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); return PopScope( - canPop: false, // Allow back navigation only if not login screen - onPopInvokedWithResult: (didPop, result) { - if (didPop) return; - context.go('/uaenumbers'); // Show exit confirmation dialog - }, + canPop: false, // Allow back navigation only if not login screen + onPopInvokedWithResult: (didPop, result) { + if (didPop) return; + context.go('/uaenumbers'); // Show exit confirmation dialog + }, - child: BaseScaffold( - key: _scaffoldKey, - // backgroundColor: color, - // appBar: AppBar( - // backgroundColor: color, - // elevation: 0, - // actions: [ - // // IconButton( - // // onPressed: () {}, - // // icon: const Icon(Icons.toggle_off_outlined), - // // ), - // MyToggle( - // // key: toggleKey, - // isOn: locale?.languageCode == 'en', - // knobTextWhenOn: 'ع', - // knobTextWhenOff: 'EN', - // pathColorWhenOn: Colors.grey.shade300, - // pathColorWhenOff: Colors.grey.shade300, - // onTap: () { - // ref.read(localeProvider.notifier).toggleLocale(); - // }, - // ), - // ], - // leading: IconButton( - // icon: Icon(Icons.arrow_back_ios_new, color: Colors.white), - // onPressed: () { - // if (widget.keyParam == 'home') { - // context.go('/myhomepage'); - // } else { - // context.go('/uaenumbers'); - // } - // }, - // ), - // title: Text( - // context.translate( - // 'UAE Numbers', - // 'أرقام الإمارات', - // ), - // style: TextStyle(color: Colors.white), - // ), - // ), - title: Text(context.translate( - 'UAE Numbers', - 'أرقام الإمارات', - ),), - // appbarColor: Color(int.parse(widget.bgColor)), // Example color - appbarColor: Color( - int.parse((chartScreenData['header_color'] ?? '#ffffff').replaceFirst('#', '0xff')) - ), - // Example color - showBackButton: true, - colorChange:true, - navBackArrow: Text(widget.keyParam ?? 'Default Value'), - 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'].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'), - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.end, - // children: [ - // IconButton( - // onPressed: () {}, - // icon: Icon( - // Icons.bookmark_add_outlined, - // color: Colors.white, - // size: 40, - // )), - // IconButton( - // onPressed: () {}, - // icon: Icon( - // Icons.share, - // color: Colors.white, - // size: 30, - // )), - // ], - // ), - ], - ), - )), + child: BaseScaffold( + key: _scaffoldKey, + // backgroundColor: color, + // appBar: AppBar( + // backgroundColor: color, + // elevation: 0, + // actions: [ + // // IconButton( + // // onPressed: () {}, + // // icon: const Icon(Icons.toggle_off_outlined), + // // ), + // MyToggle( + // // key: toggleKey, + // isOn: locale?.languageCode == 'en', + // knobTextWhenOn: 'ع', + // knobTextWhenOff: 'EN', + // pathColorWhenOn: Colors.grey.shade300, + // pathColorWhenOff: Colors.grey.shade300, + // onTap: () { + // ref.read(localeProvider.notifier).toggleLocale(); + // }, + // ), + // ], + // leading: IconButton( + // icon: Icon(Icons.arrow_back_ios_new, color: Colors.white), + // onPressed: () { + // if (widget.keyParam == 'home') { + // context.go('/myhomepage'); + // } else { + // context.go('/uaenumbers'); + // } + // }, + // ), + // title: Text( + // context.translate( + // 'UAE Numbers', + // 'أرقام الإمارات', + // ), + // style: TextStyle(color: Colors.white), + // ), + // ), + title: Text( + context.translate( + 'UAE Numbers', + 'أرقام الإمارات', + ), + ), + // appbarColor: Color(int.parse(widget.bgColor)), // Example color + appbarColor: Color(int.parse( + (chartScreenData['header_color'] ?? '#ffffff') + .replaceFirst('#', '0xff'))), + // Example color + showBackButton: true, + colorChange: true, + navBackArrow: Text(widget.keyParam ?? 'Default Value'), + body: isLoading + ? Center(child: CircularProgressIndicator()) + : Container( + color: color, + child: Column( + children: [ Container( - color: Color(int.parse(chartScreenData['header_color'].replaceFirst('#', '0xff'))), - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Row( - key: bookMarkKey, - children: [ - Text( - context.translate( - 'Bookmark', - 'إشارة مرجعية', - ), - style: const TextStyle( - fontSize: 16, + // 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, - ), - ), - SizedBox(width: 5), - GestureDetector( - onTap: () { - if (isBookmarked) { - showRemoveBookmarkDialog(); - } else { - showAddBookmarkDialog(); - } - }, + 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'), + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // IconButton( + // onPressed: () {}, + // icon: Icon( + // Icons.bookmark_add_outlined, + // color: Colors.white, + // size: 40, + // )), + // IconButton( + // onPressed: () {}, + // icon: Icon( + // Icons.share, + // color: Colors.white, + // size: 30, + // )), + // ], + // ), + ], + ), + )), + 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: Row( + children: [ + Text( + context.translate( + 'Bookmark', + 'إشارة مرجعية', + ), + style: const TextStyle( + fontSize: 16, + color: Colors.white, + ), + ), + SizedBox(width: 5), - child: Row( + // 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( + Icons.bookmarks_rounded, + color: isBookmarked + ? Colors.black + : Colors.white, + ), + ], + ), + ), + ], + ), + SizedBox(width: 10), + Row( + children: [ + Text( + context.translate( + 'Share', + 'يشارك', + ), + style: const TextStyle( + fontSize: 16, + color: Colors.white, + ), + ), + SizedBox(width: 5), + Stack( children: [ - // 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, + // UaeNumbersAssetPath.shareUae, + // color: Colors.white, // Outline color + // width: 24, // Slightly larger + // height: 24, + // ), + // Image.asset( + // UaeNumbersAssetPath.shareUae, + // color: Colors.white, // width: 24, // height: 24, // ), - Icon(Icons.bookmarks_rounded, color:isBookmarked ? Colors.black:Colors.white,size: 20,), + SvgPicture.asset( + UaeNumbersAssetPath.share, + semanticsLabel: 'share', + width: 24, + height: 24, + ), ], + ) + ], + ), + SizedBox( + width: 10), // Horizontal space between items + Row( + children: [ + Text( + context.translate( + 'Filter', + 'فلتر', + ), + style: const TextStyle( + fontSize: 16, + color: Colors.white, + ), ), - ), - ], - ), - SizedBox(width: 10), - Row( - children: [ - Text( - context.translate( - 'Share', - 'يشارك', + GestureDetector( + onTap: () { + showRightSideModal( + context, filterData, chartsData); + }, + child: Image.asset( + UaeNumbersAssetPath.filterUae, + color: Colors.white, // Set color to white + width: 21, + height: 21, + ), + ) + // 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, + // crossAxisCount: cardData.length == 2 + // ? 2 + // : cardData.length == 3 + // ? 3 + // : cardData.length == 4 + // ? 2 + // : 3, // Default to 3 if more than 4 items // 2 cards per row + crossAxisSpacing: 2, + mainAxisSpacing: 5, + childAspectRatio: MediaQuery.of(context) + .size + .width / + (MediaQuery.of(context).size.height / + (cardData.length % 2 == 0 + ? 2 + : 1.3)), + // childAspectRatio: + // calculateAspectRatio(cardData.length, cardData), ), - style: const TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - SizedBox(width: 5), - Stack( - children: [ - // Image.asset( - // UaeNumbersAssetPath.shareUae, - // color: Colors.white, // Outline color - // width: 24, // Slightly larger - // height: 24, - // ), - // Image.asset( - // UaeNumbersAssetPath.shareUae, - // color: Colors.white, - // width: 24, - // height: 24, - // ), - SvgPicture.asset( - UaeNumbersAssetPath.share, - semanticsLabel: 'share', - width: 24, - height: 24, - ), - //share icon - // Icon(Icons.share_sharp,color: Colors.white,size: 20,), - ], - ) - ], - ), - SizedBox( - width: 10), // Horizontal space between items - Row( - children: [ - Text( - context.translate( - 'Filter', - 'فلتر', - ), - style: const TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - IconButton( - icon: Icon(Icons.filter_alt_outlined,weight: 400, - color: Colors.white, size: 24), - onPressed: () { - showRightSideModal( - context, filterData, chartsData); + // 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 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; + + if (response.isEmpty) { + return const SizedBox.shrink(); + // return Container( + // color: Colors.redAccent, + // ); + } + if (response.length == 1) { + return Container( + margin: const EdgeInsets.all(10), + 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), + 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), + Flexible( + fit: FlexFit.loose, + // child: FittedBox( + child: Text( + '${chart_heading ?? 'NA'}', + textAlign: + TextAlign.center, + maxLines: 2, + // Limit to 2 lines + softWrap: true, + // Enable soft wrapping + // overflow: TextOverflow.ellipsis, // Handle overflow gracefully + style: TextStyle( + fontSize: 9, + fontWeight: + FontWeight.w400, + color: Colors.black87, + ), + ), + // ), + ), + const SizedBox(height: 5), + Flexible( + fit: FlexFit.loose, + child: FittedBox( + child: Text( + '(${response[0]['display_value'] ?? 'NA'})', + // '(${data['firstYear'] ?? + // 'NA'} - ${data['lastYear'] ?? + // 'NA'})', + style: const TextStyle( + fontSize: 10, + color: Colors.grey), + ), + ), + ), + const SizedBox(height: 1), + Flexible( + fit: FlexFit.loose, + child: SizedBox( + height: 50.0, + child: FittedBox( + fit: BoxFit.contain, + child: Text( + response[0] + ['value'] ?? + 'NA', + // '${data['roundedAverage'] ?? + // 'NA'}', + style: + const TextStyle( + fontSize: 20, + fontWeight: + FontWeight.w900, + color: Color( + 0xFF90B0D5), + ), + ), + ), + ), + ), + ], + ), + ), + )); + } else { + return Container( + margin: const EdgeInsets.all(10), + 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), + 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), + Flexible( + fit: FlexFit.loose, + child: FittedBox( + child: SizedBox( + // height: 70.0, + child: Text( + '${chart_heading ?? 'NA'}', + // "TOTAL", + textAlign: + TextAlign.center, + maxLines: + 2, // Limit to 2 lines + softWrap: + true, // Enable soft wrapping + // overflow: TextOverflow.ellipsis, // Handle overflow gracefully + style: TextStyle( + fontSize: 8, + fontWeight: + FontWeight.w400, + color: Colors.black87, + ), + ), + ), + ), + ), + const SizedBox(height: 1), + Text( + '(${response[0]['display_value'] ?? 'NA'})', + + // '(${data['lastYear'] ?? 'NA'})', + style: const TextStyle( + fontSize: 10, + color: Colors.grey), + ), + const SizedBox(height: 1), + Flexible( + fit: FlexFit.loose, + child: FittedBox( + fit: BoxFit.contain, + child: Text( + response[0]['value'] ?? + 'NA', + + // apiService.formatAmount( + // data['lastYearValue']), + // apiService.formatAmount( + // data['lastYearValue']), + style: const TextStyle( + fontSize: 18, + fontWeight: + FontWeight.w900, + color: + Color(0xFF90B0D5), + ), + ), + ), + ), + SizedBox( + height: + 2, // Height of the divider + child: Divider( + color: Color(0xFFBBBCBD), + thickness: + 1, // Divider line thickness + ), + ), + Flexible( + fit: FlexFit.loose, + child: FittedBox( + fit: BoxFit.contain, + child: Text( + response[1]['value'] ?? + 'NA', + // apiService.formatAmount( + // data['secondLastYearValue']), + style: const TextStyle( + fontSize: 14, + fontWeight: + FontWeight.w600, + color: + Color(0xFFD83731), + ), + ), + ), + ), + Text( + '(${response[1]['display_value'] ?? 'NA'})', + // '(${data['secondLastYear'] ?? 'NA'})', + style: const TextStyle( + fontSize: 9, + fontWeight: + FontWeight.w500, + color: Colors.grey), + ), + ], + ), + ), + ), + ); + } }, ), - - ], - ), - SizedBox( - width: 10), - ], - ), - ], - ), - ), - Expanded( - child: Container( - color: Color(int.parse(chartScreenData['body_color'].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, - ); - }), - ), - ), + // chartsData Cards + ListView.builder( + itemCount: chartsData.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return Card( + margin: const EdgeInsets.all(10), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + ConstrainedBox( + constraints: const BoxConstraints( + minHeight: + 200, // Minimum height + maxHeight: + 400, // Maximum height + ), + // child: buildChart(chartsData[index]), + child: ChartWidget( + chartData: + chartsData[index])), + ], + ), + ), + ); + }, ), - // 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: cardData.length == 2 - ? 2 - : cardData.length == 3 - ? 3 - : cardData.length == 4 - ? 2 - : 3, // Default to 3 if more than 4 items // 2 cards per row - crossAxisSpacing: 2, - mainAxisSpacing: 5, - childAspectRatio: - calculateAspectRatio(cardData.length, 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_logo = item['card_logo']; - final data = apiService.processNonChartData(item); - print('processNonChartData'); - - double cardHeight = (chart_type == 'totals' || - chart_type == 'averages') - ? 180.0 - : 130.0; - - if (chart_type == 'total') { - return - Container( - margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all( - color: Color(int.parse(chartScreenData['border_color'].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), - 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), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - child: SizedBox( - // height: 70.0, - child: Text( - '${chart_heading ?? 'NA'}', - textAlign: TextAlign.center, - maxLines: 2, // Limit to 2 lines - softWrap: - true, // Enable soft wrapping - // overflow: TextOverflow.ellipsis, // Handle overflow gracefully - style: TextStyle( - fontSize: 8, - fontWeight: FontWeight.w400, - color: Colors.black87, - ), - ), - ), - ), - ), - const SizedBox(height: 1), - Text( - '(${data['lastYear'] ?? 'NA'})', - style: const TextStyle( - fontSize: 10, color: Colors.grey), - ), - const SizedBox(height: 1), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - fit: BoxFit.contain, - child: Text( - apiService.formatAmount( - data['lastYearValue']), - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.w900, - color: Color(0xFF90B0D5), - ), - ), - ), - ), - SizedBox( - height: 2, // Height of the divider - child: Divider( - color: Colors.grey, - thickness: - 1, // Divider line thickness - ), - ), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - fit: BoxFit.contain, - child: Text( - apiService.formatAmount( - data['secondLastYearValue']), - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Color(0xFFD83731), - ), - ), - ), - ), - Text( - '(${data['secondLastYear'] ?? 'NA'})', - style: const TextStyle( - fontSize: 9, - fontWeight: FontWeight.w500, - color: Colors.grey), - ), - ], - ), - ), - ),); - - - - } else if (chart_type == 'average') { - return Container( - margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all( - color: Color(int.parse(chartScreenData['border_color'].replaceFirst('#', '0xff'))), // Dynamic border color - width: 1, // Adjust border thickness - ), - ), - child: Card( - margin: const EdgeInsets.all(0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - elevation: 4, - child: Container( - height: cardHeight, - padding: const EdgeInsets.all(16.0), - 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), - Flexible( - fit: FlexFit.loose, - // child: FittedBox( - child: Text( - '${chart_heading ?? 'NA'}', - textAlign: TextAlign.center, - maxLines: 2, // Limit to 2 lines - softWrap: - true, // Enable soft wrapping - // overflow: TextOverflow.ellipsis, // Handle overflow gracefully - style: TextStyle( - fontSize: 9, - fontWeight: FontWeight.w400, - color: Colors.black87, - ), - ), - // ), - ), - const SizedBox(height: 5), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - child:Text( - '(${data['firstYear'] ?? 'NA'} - ${data['lastYear'] ?? 'NA'})', - style: const TextStyle( - fontSize: 10, color: Colors.grey), - ),),), - const SizedBox(height: 1), - Flexible( - fit: FlexFit.loose, - child: SizedBox( - height: 50.0, - child: FittedBox( - fit: BoxFit.contain, - child: Text( - '${data['roundedAverage'] ?? 'NA'}', - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.w900, - color: Color(0xFF90B0D5), - ), - ), - ), - ), - ), - ], - ), - ), - )); - } else if (chart_type == 'totals') { - return Container( - margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all( - color: Color(int.parse(chartScreenData['border_color'].replaceFirst('#', '0xff'))), // Dynamic border color - width: 1, // Adjust border thickness - ), - ), - child: Card( - margin: const EdgeInsets.all(0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - elevation: 4, - child: Container( - height: cardHeight, - // height: maxHeight, - // padding: const EdgeInsets.all(10.0), - padding: const EdgeInsets.symmetric( - vertical: 0, horizontal: 10), - child: Column( - // mainAxisSize: MainAxisSize.min, // Adjust card height based on content - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.public, - color: Color(0xFF90B0D5), size: 30), - const SizedBox(height: 3), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - child: Text( - '${chart_heading ?? 'NA'}', - textAlign: TextAlign.center, - maxLines: 2, // Limit to 2 lines - softWrap: - true, // Enable soft wrapping - // overflow: TextOverflow.ellipsis, // Handle overflow gracefully - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w400, - color: Colors.black87, - ), - ), - ), - ), - Text( - '(${data['lastYear'] ?? 'NA'})', - style: const TextStyle( - fontSize: 11, color: Colors.grey), - ), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - fit: BoxFit.contain, - child: Text( - apiService.formatAmount( - data['lastYearValue']), - style: const TextStyle( - fontSize: 22, - fontWeight: FontWeight.w900, - color: Color(0xFF90B0D5), - ), - ), - ), - ), - ], - ), - ), - )); - - } else if (chart_type == 'averages') { - return Container( - margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - border: Border.all( - color: Color(int.parse(chartScreenData['border_color'].replaceFirst('#', '0xff'))), // Dynamic border color - width: 1, // Adjust border thickness - ), - ), - child: Card( - margin: const EdgeInsets.all(0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - elevation: 4, - child: Container( - // height: maxHeight, - // height: 200, - height: cardHeight, - padding: const EdgeInsets.all(5.0), - // padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 10), - child: Column( - // mainAxisSize: MainAxisSize.min, // Adjust card height based on content - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.public, - color: Color(0xFF90B0D5), size: 30), - const SizedBox(height: 5), - Text( - '${chart_heading ?? 'NA'}', - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w400, - color: Colors.black87, - ), - ), - Text( - '(${data['lastYear'] ?? 'NA'})', - style: const TextStyle( - fontSize: 11, color: Colors.grey), - ), - const SizedBox(height: 5), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - child: Text( - '${chart_heading ?? 'NA'}', - textAlign: TextAlign.center, - maxLines: 2, // Limit to 2 lines - softWrap: - true, // Enable soft wrapping - // overflow: TextOverflow.ellipsis, // Handle overflow gracefully - style: TextStyle( - fontSize: 11, - fontWeight: FontWeight.w400, - color: Colors.black87, - ), - ), - ), - ), - ], - ), - ), - )); - } else { - return const SizedBox - .shrink(); // Ignore unknown KPIs - } - }, + ], ), ), - // chartsData Cards - ListView.builder( - itemCount: chartsData.length, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return Card( - margin: const EdgeInsets.all(10), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 10), - Container( - height: 300, - // child: buildChart(chartsData[index]), - child: ChartWidget( - chartData: chartsData[index])), - ], - ), - ), - ); - }, - ), - ], - ), - ), - ), + ), + ), + ], ), - ], - ), - ), - ),); + ), + ), + ); } Widget _buildArrowButton( @@ -2670,4 +2659,4 @@ class _ChartScreen1State extends ConsumerState { ), ); } -} \ No newline at end of file +} diff --git a/lib/presentation/Screens/charts/widgets/chart_widget.dart b/lib/presentation/Screens/charts/widgets/chart_widget.dart index d27c4c88..57c3690a 100644 --- a/lib/presentation/Screens/charts/widgets/chart_widget.dart +++ b/lib/presentation/Screens/charts/widgets/chart_widget.dart @@ -231,6 +231,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 20), Expanded( child: ValueListenableBuilder( @@ -261,21 +270,23 @@ class ChartWidget extends StatelessWidget { ), ), SizedBox(height: 25), - Flexible( child: SingleChildScrollView( scrollDirection: Axis.vertical, child: Container( - constraints: BoxConstraints(minHeight: 5), // Allow dynamic height + constraints: + BoxConstraints(minHeight: 5), // Allow dynamic height child: Padding( - padding: const EdgeInsets.only(left: 8.0 ,right: 8.0,bottom: 8.0,top:20.0), - child: Wrap( - spacing: 12, - runSpacing: 8, - children: generateIndicators(chartData, chartData['group_by']), - ), - ), - ), + padding: const EdgeInsets.only( + left: 8.0, right: 8.0, bottom: 8.0, top: 20.0), + child: Wrap( + spacing: 12, + runSpacing: 8, + children: + generateIndicators(chartData, chartData['group_by']), + ), + ), + ), ), ), ], @@ -305,6 +316,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), AspectRatio( aspectRatio: 1.5, @@ -520,6 +540,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), // Chart Expanded( @@ -622,6 +651,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), Expanded( @@ -629,8 +667,8 @@ class ChartWidget extends StatelessWidget { scrollDirection: Axis.horizontal, // Enable horizontal scrolling padding: const EdgeInsets.only(right: 40), child: SizedBox( - width: (uniqueXValues.length * 80) + - 80, // Adjust width dynamically + width: (uniqueXValues.length * 50) + + 50, // Adjust width dynamically child: LineChart(LineChartData( lineTouchData: lineTouchData1(), gridData: gridData(), @@ -733,6 +771,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), // Chart Expanded( @@ -740,8 +787,8 @@ class ChartWidget extends StatelessWidget { scrollDirection: Axis.horizontal, // Enable horizontal scrolling padding: const EdgeInsets.only(right: 40), child: SizedBox( - width: (uniqueXValues.length * 80) + - 80, // Adjust width dynamically + width: (uniqueXValues.length * 50) + + 50, // Adjust width dynamically child: LineChart( LineChartData( lineTouchData: lineTouchData1(), @@ -751,6 +798,7 @@ class ChartWidget extends StatelessWidget { lineBarsData: lineBars, minX: uniqueXValues.reduce((a, b) => a < b ? a : b), maxX: uniqueXValues.reduce((a, b) => a > b ? a : b), + minY: 0, ), ), ), @@ -779,6 +827,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), // Chart Expanded( @@ -886,6 +943,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), // Chart Expanded( @@ -896,7 +962,22 @@ class ChartWidget extends StatelessWidget { ? yAxisData.reduce((a, b) => a > b ? a : b) * 1.2 : 10, rotationQuarterTurns: rotationTurns, - barTouchData: BarTouchData(enabled: true), + barTouchData: BarTouchData( + enabled: true, + handleBuiltInTouches: true, + touchTooltipData: BarTouchTooltipData( + fitInsideHorizontally: true, + fitInsideVertically: true, + tooltipPadding: const EdgeInsets.all(8), + tooltipMargin: 16, + getTooltipItem: (group, groupIndex, rod, rodIndex) { + return BarTooltipItem( + '${rod.toY.toStringAsFixed(1)}', + const TextStyle(color: Colors.white), + ); + }, + ), + ), titlesData: FlTitlesData( leftTitles: AxisTitles( sideTitles: SideTitles( @@ -925,11 +1006,11 @@ class ChartWidget extends StatelessWidget { // angle: -45 * // (3.1415927 / 180), // Rotating by -45 degrees alignment: Alignment.center, - child: Center( + child: Center( child: SizedBox( width: 100, child: Text( - xAxisData[value.toInt()], + xAxisData[value.toInt()], style: const TextStyle(fontSize: 12), softWrap: true, maxLines: 2, @@ -977,39 +1058,15 @@ class ChartWidget extends StatelessWidget { const double barWidth = 30; // Width for each bar, including spacing return totalBars * barWidth; // Calculate total chart width } + String cropKey = chartData['chart_type_json']['x_sub_group']; // Group crops by CROP_TYPE Map> groupedCrops = {}; int touchedGroupIndex = -1; // Iterate over the chartData to group crops by CROP_TYPE for (var item in chartData['response']) { String crop, cropType; - if (chartData['dataset'] == 'health_services') { - crop = item['ObsKey']['SECTOR']; - cropType = item['ObsKey'][groupByKey]; - } else if (chartData['dataset'] == 'general_education') { - print(chartData['dataset'] == 'general_education'); - crop = item['ObsKey']['GENDER']; - cropType = item['ObsKey'][groupByKey]; - } else if (chartData['dataset'] == 'higher_education') { - crop = item['ObsKey']['GENDER']; - cropType = item['ObsKey'][groupByKey]; - } else if (chartData['dataset'] == 'labour_force') { - crop = item['ObsKey']['GENDER']; - cropType = item['ObsKey'][groupByKey]; - } else if (chartData['dataset'] == 'clinics') { - - if (kDebugMode) { - print('forclinics'); - print('ObsKey: ${item['ObsKey']}'); - // print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}'); - } - - crop = item['ObsKey']['MEASURE']; - cropType = item['ObsKey'][groupByKey]; - } else { - crop = item['ObsKey']['CROP']; - cropType = item['ObsKey'][groupByKey]; - } + crop = item['ObsKey'][cropKey]; + cropType = item['ObsKey'][groupByKey]; if (groupedCrops.containsKey(cropType)) { groupedCrops[cropType]!.add(crop); @@ -1026,6 +1083,15 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), // Chart Expanded( @@ -1187,64 +1253,17 @@ class ChartWidget extends StatelessWidget { ]); case 'horizontal_rotate': + String cropKey = chartData['chart_type_json'] + ['y_sub_group']; // Dynamically get crop key // Group crops by CROP_TYPE Map> groupedCrops = {}; // Iterate over the chartData to group crops by CROP_TYPE for (var item in chartData['response']) { String crop, cropType; - if (chartData['dataset'] == 'natural_reserves') { - crop = item['ObsKey']['NR_TYPE']; - cropType = item['ObsKey'][groupByKey]; - } - else if(chartData['dataset'] == 'gdp') - { - print("ForGDP"); - if (kDebugMode) { - - print('ObsKey: ${item['ObsKey']}'); - // print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}'); - } - crop = item['ObsKey']['BOP_ITEM']; - - cropType = item['ObsKey'][groupByKey]; - } else if(chartData['dataset'] == 'air_transport') - { - print("Forair_transport"); - if (kDebugMode) { - - print('ObsKey: ${item['ObsKey']}'); - // print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}'); - } - crop = item['ObsKey']['MEASURE']; - - cropType = item['ObsKey'][groupByKey]; - } else if(chartData['dataset'] == 'import') - { - print("Forimport"); - if (kDebugMode) { - - print('ObsKey: ${item['ObsKey']}'); - // print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}'); - } - crop = item['ObsKey']['COUNTRY']; - - cropType = item['ObsKey'][groupByKey]; - } - else if(chartData['dataset'] == 'gdpq') - { - print("ForGDPq"); - if (kDebugMode) { - print('ObsKey: ${item['ObsKey']}'); - } - crop = item['ObsKey']['MEASURE']; - // crop = item['ObsKey']['TIME_PERIOD']; - cropType = item['ObsKey'][groupByKey]; - } - else { - crop = item['ObsKey']['CROP']; - cropType = item['ObsKey'][groupByKey]; - } + // crop = item['ObsKey']['CROP']; + crop = item['ObsKey'][cropKey]; + cropType = item['ObsKey'][groupByKey]; if (groupedCrops.containsKey(cropType)) { groupedCrops[cropType]!.add(crop); @@ -1257,16 +1276,17 @@ class ChartWidget extends StatelessWidget { int rotationTurns = 1; print('Grouped Crops: $groupedCrops'); - int numberOfBars = groupedCrops.length; // Number of grouped sets (bar groups) + int numberOfBars = + groupedCrops.length; // Number of grouped sets (bar groups) double barHeight = 40.0; // Height per individual bar double barSpacing = 30.0; // Space between bar sets double minHeight = 300.0; // Minimum chart height double maxHeight = 1000.0; // Maximum chart height // Calculate total height dynamically - double chartHeight = ((numberOfBars * barHeight) + ((numberOfBars - 1) * barSpacing)) - .clamp(minHeight, maxHeight); - + double chartHeight = + ((numberOfBars * barHeight) + ((numberOfBars - 1) * barSpacing)) + .clamp(minHeight, maxHeight); return Column(children: [ Text( @@ -1277,169 +1297,184 @@ class ChartWidget extends StatelessWidget { ), textAlign: TextAlign.center, ), + SizedBox(height: 5), + Text( + chartData['chart_sub_heading'] ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w300, + ), + textAlign: TextAlign.center, + ), SizedBox(height: 10), // Chart Expanded( - child: SingleChildScrollView( - scrollDirection: Axis.vertical, child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child:SizedBox( - width: 1000, - height: chartHeight, - child: BarChart( - BarChartData( - maxY: 400000, - rotationQuarterTurns: rotationTurns, - barTouchData: BarTouchData( - touchTooltipData: BarTouchTooltipData( - tooltipHorizontalAlignment: FLHorizontalAlignment.center, - tooltipRoundedRadius: 8, - fitInsideHorizontally: - true, // Ensure it fits within the screen - fitInsideVertically: true, - tooltipPadding: EdgeInsets.all(8), - tooltipMargin: 16, - // Only show tooltip when touched - getTooltipItem: (group, groupIndex, rod, rodIndex) { - if (rod.toY == 0 || touchedGroupIndex == -1) { - return null; // Don't show the tooltip if the value is 0 or there's no touch - } + scrollDirection: Axis.vertical, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: SizedBox( + width: 1000, + height: chartHeight, + child: BarChart( + BarChartData( + maxY: 400000, + rotationQuarterTurns: rotationTurns, + barTouchData: BarTouchData( + touchTooltipData: BarTouchTooltipData( + tooltipHorizontalAlignment: + FLHorizontalAlignment.center, + tooltipRoundedRadius: 8, + fitInsideHorizontally: + true, // Ensure it fits within the screen + fitInsideVertically: true, + tooltipPadding: EdgeInsets.all(8), + tooltipMargin: 16, + // Only show tooltip when touched + getTooltipItem: (group, groupIndex, rod, rodIndex) { + if (rod.toY == 0 || touchedGroupIndex == -1) { + return null; // Don't show the tooltip if the value is 0 or there's no touch + } - if (groupIndex == touchedGroupIndex) { - // print('Group Index: $groupIndex, Group : $group'); + if (groupIndex == touchedGroupIndex) { + // print('Group Index: $groupIndex, Group : $group'); - // Get the group label dynamically - String groupLabel = groupByValues.elementAt(groupIndex); + // Get the group label dynamically + String groupLabel = + groupByValues.elementAt(groupIndex); - // Fetch the crop for the current group from groupedCrops - String cropType = groupByValues.elementAt(groupIndex); - String crop = groupedCrops[cropType]![rodIndex]; - double value = rod.toY; + // Fetch the crop for the current group from groupedCrops + String cropType = + groupByValues.elementAt(groupIndex); + String crop = groupedCrops[cropType]![rodIndex]; + double value = rod.toY; - String formattedValue; - if (value >= 1000000) { - formattedValue = - (value / 1000000).toStringAsFixed(1) + 'M'; - } else if (value >= 1000) { - formattedValue = - (value / 1000).toStringAsFixed(1) + 'K'; - } else { - formattedValue = value.toStringAsFixed( - 0); // for values smaller than 1000 - } + String formattedValue; + if (value >= 1000000) { + formattedValue = + (value / 1000000).toStringAsFixed(1) + 'M'; + } else if (value >= 1000) { + formattedValue = + (value / 1000).toStringAsFixed(1) + 'K'; + } else { + formattedValue = value.toStringAsFixed( + 0); // for values smaller than 1000 + } - return BarTooltipItem( - '$groupLabel\n$crop', - const TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - ), - children: [ - TextSpan( - text: ' Value: $formattedValue', - style: const TextStyle( - color: Colors.yellow, - fontWeight: FontWeight.w500, + return BarTooltipItem( + '$groupLabel\n$crop', + const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, ), - ), - ], - ); - } - return null; - }, - ), - touchCallback: (event, response) { - if (event.isInterestedForInteractions && - response != null && - response.spot != null) { - // setState(() { - touchedGroupIndex = response.spot!.touchedBarGroupIndex; - // }); - } else { - // setState(() { - touchedGroupIndex = -1; // Reset if no interaction - // }); - } - }, - ), - titlesData: FlTitlesData( - leftTitles: AxisTitles( - sideTitles: SideTitles( - showTitles: false, - reservedSize: 20, - interval: 100000, - getTitlesWidget: (value, meta) { - return Text( - value.toInt().toString(), - style: const TextStyle(fontSize: 12), - ); - }, - ), - ), - bottomTitles: AxisTitles( - sideTitles: SideTitles( - showTitles: true, - reservedSize: 80, // Added space for rotated titles - getTitlesWidget: (value, meta) { - if (value < groupByValues.length) { - String title = groupByValues.elementAt(value.toInt()); - return Transform.rotate( - angle: -1.58, // Rotation in radians (~ -30 degrees) - child: Center( - child: SizedBox( - width: 80, - child: Text( - title, - style: const TextStyle(fontSize: 12), - softWrap: true, - maxLines: 2, + children: [ + TextSpan( + text: ' Value: $formattedValue', + style: const TextStyle( + color: Colors.yellow, + fontWeight: FontWeight.w500, + ), ), - ), - ), - ); + ], + ); + } + return null; + }, + ), + touchCallback: (event, response) { + if (event.isInterestedForInteractions && + response != null && + response.spot != null) { + // setState(() { + touchedGroupIndex = + response.spot!.touchedBarGroupIndex; + // }); + } else { + // setState(() { + touchedGroupIndex = -1; // Reset if no interaction + // }); } - return const SizedBox.shrink(); }, ), - ), - rightTitles: - AxisTitles(sideTitles: SideTitles(showTitles: false)), - topTitles: - AxisTitles(sideTitles: SideTitles(showTitles: false)), - ), - borderData: FlBorderData( - show: true, - border: const Border( - // left: BorderSide(color: Colors.grey), - bottom: BorderSide(color: Colors.white), + titlesData: FlTitlesData( + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: false, + reservedSize: 20, + interval: 100000, + getTitlesWidget: (value, meta) { + return Text( + value.toInt().toString(), + style: const TextStyle(fontSize: 12), + ); + }, + ), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 80, // Added space for rotated titles + getTitlesWidget: (value, meta) { + if (value < groupByValues.length) { + String title = + groupByValues.elementAt(value.toInt()); + return Transform.rotate( + angle: + -1.58, // Rotation in radians (~ -30 degrees) + child: Center( + child: SizedBox( + width: 80, + child: Text( + title, + style: const TextStyle(fontSize: 12), + softWrap: true, + maxLines: 2, + ), + ), + ), + ); + } + return const SizedBox.shrink(); + }, + ), + ), + rightTitles: + AxisTitles(sideTitles: SideTitles(showTitles: false)), + topTitles: + AxisTitles(sideTitles: SideTitles(showTitles: false)), + ), + borderData: FlBorderData( + show: true, + border: const Border( + // left: BorderSide(color: Colors.grey), + bottom: BorderSide(color: Colors.white), + ), + ), + gridData: FlGridData( + show: false, + drawVerticalLine: true, + verticalInterval: 1, + horizontalInterval: 100000, + getDrawingHorizontalLine: (value) { + return FlLine( + color: Colors.grey.withOpacity(0.5), + strokeWidth: 1, + ); + }, + getDrawingVerticalLine: (value) { + return FlLine( + color: Colors.grey.withOpacity(0.5), + strokeWidth: 1, + ); + }, + ), + barGroups: _buildHorizontalRotateBarGroups( + chartData, groupByValues), + alignment: BarChartAlignment.spaceAround, ), ), - gridData: FlGridData( - show: false, - drawVerticalLine: true, - verticalInterval: 1, - horizontalInterval: 100000, - getDrawingHorizontalLine: (value) { - return FlLine( - color: Colors.grey.withOpacity(0.5), - strokeWidth: 1, - ); - }, - getDrawingVerticalLine: (value) { - return FlLine( - color: Colors.grey.withOpacity(0.5), - strokeWidth: 1, - ); - }, - ), - barGroups: - _buildHorizontalRotateBarGroups(chartData, groupByValues), - alignment: BarChartAlignment.spaceAround, ), ), - ), - ), )), // Expanded( // child: Stack( @@ -1837,12 +1872,15 @@ class ChartWidget extends StatelessWidget { bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, - interval: 1, // Ensure each year is shown only once + interval: 10, // Ensure each year is shown only once getTitlesWidget: (value, meta) { if (xValues.contains(value)) { - return Text( - value.toInt().toString(), - style: TextStyle(color: Colors.black, fontSize: 12), + return Transform.rotate( + angle: -0.5, // Slight rotation to improve readability + child: Text( + value.toInt().toString(), + style: TextStyle(color: Colors.black, fontSize: 12), + ), ); } else { return SizedBox.shrink(); // Hide non-relevant labels @@ -2109,9 +2147,8 @@ class ChartWidget extends StatelessWidget { chartData['dataset'] == 'higher_education' || chartData['dataset'] == 'air_transport' || chartData['dataset'] == 'labour_force' || - chartData['dataset'] == 'gdp' - ) { - + chartData['dataset'] == 'gdp' || + chartData['dataset'] == 'clinics') { barColor = uniqueColorsForTwo[colorIndex % uniqueColorsForTwo.length]; colorIndex++; } else { diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart index f3ce6694..415365de 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart @@ -21,6 +21,7 @@ class _ManageUserRouterState extends State { int _sortColumnIndex = 0; bool _isAscending = true; List filteredUserData = []; + bool isLoading = true; // final List statusOptions = ['Approved', 'Denied', 'Pending']; @@ -52,9 +53,9 @@ class _ManageUserRouterState extends State { ); setState(() { + isLoading = true; userData = result.map((record) { - final createdDate = - DateTime.parse(record.created); // Parse the created date + final createdDate = DateTime.parse(record.created).add(Duration(hours: 4));// Parse the created date final formattedDate = DateFormat('dd/MM/yyyy').format(createdDate); return User( id: record.id, // Correctly passing the ID @@ -64,7 +65,17 @@ class _ManageUserRouterState extends State { status: record.getStringValue('status'), ); }).toList(); + + userData.sort((a,b){ + DateTime dateA= DateFormat('dd/MM/yyyy').parse(a.registrationDate); + DateTime dateB = DateFormat('dd/MM/yyyy').parse(b.registrationDate); + return dateB.compareTo(dateA); + }); + + filteredUserData = List.from(userData); + + isLoading = false; }); } catch (e) { print('Error fetching unverified users: $e'); @@ -338,6 +349,7 @@ class _ManageUserRouterState extends State { image: ExactAssetImage(MiscIconAssetPath.search), width: 24, height: 24, + color: Color(0xFFAA8E83) ), @@ -349,10 +361,13 @@ class _ManageUserRouterState extends State { contentPadding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0), ), + onChanged: filterUsers, ),), ), SizedBox(height: myheight / 40), - filteredUserData.isEmpty + isLoading + ? Center(child: CircularProgressIndicator()) + :filteredUserData.isEmpty ? Center( child: Padding( padding: const EdgeInsets.all(16.0), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart index 8a41b7f9..7fe036ed 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:intl/intl.dart'; +import 'package:pocketbase/pocketbase.dart'; import '../../custom_drawer_routes.dart'; class NotificationPage extends StatefulWidget { @@ -9,23 +11,63 @@ class NotificationPage extends StatefulWidget { class _NotificationPageState extends State { // Example notification data - List> notifications = [ - {"title": "Social datasets are updated", "date": "04 Nov 2024 08:25 PM", "category": "Social"}, - {"title": "New feature updated", "date": "04 Nov 2024 08:25 PM", "category": "App updates"}, - ]; + final _pb = PocketBase('https://pb.venbait.in'); + List> notifications = []; // Current selected tab index int selectedTabIndex = 0; // Tab categories - final List tabs = ["All updates", "App updates", "Social", "Economy", "Environment", "Favourites"]; + final List tabs = [ + "All updates", + "App updates", + "Social", + "Economy", + "Environment", + "Favourites" + ]; + + String formatDate(String dateString) { + try { + DateTime dateTime = + DateTime.parse(dateString); // Convert API date to DateTime + return DateFormat('dd MMM yyyy hh:mm a') + .format(dateTime); // Format DateTime + } catch (e) { + return 'Invalid Date'; // Handle parsing errors + } + } + + Future fetchNotifications() async { + try { + await _pb.admins + .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); + + final result = await _pb.collection('notification').getFullList(); + + setState(() { + notifications = result.map((record) => record.toJson()).toList(); + }); + } catch (e) { + print('Error fetching notifications: $e'); + } + } + + @override + void initState() { + super.initState(); + fetchNotifications(); + } @override Widget build(BuildContext context) { // Filter notifications based on the selected tab List> filteredNotifications = selectedTabIndex == 0 ? notifications - : notifications.where((notification) => notification["category"] == tabs[selectedTabIndex]).toList(); + : notifications + .where((notification) => + notification["category"] == tabs[selectedTabIndex]) + .toList(); return PopScope( canPop: false, @@ -49,49 +91,51 @@ class _NotificationPageState extends State { Expanded( child: selectedTabIndex == 1 ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Image.asset( - 'assets/backgrounds/Notification/Update_notific.png', - height: 200, - ), - SizedBox(height: 16), - Text( - filteredNotifications.isNotEmpty - ? filteredNotifications[0]['title'] - : 'No updates available.', - style: TextStyle(fontSize: 16, color: Colors.grey), - textAlign: TextAlign.center, - ), - ], - ), - ) + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/backgrounds/Notification/Update_notific.png', + height: 200, + ), + SizedBox(height: 16), + Text( + filteredNotifications.isNotEmpty + ? filteredNotifications[0]['title'] + : 'No updates available.', + style: TextStyle(fontSize: 16, color: Colors.grey), + textAlign: TextAlign.center, + ), + ], + ), + ) : filteredNotifications.isEmpty - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.info_outline, size: 100, color: Colors.grey[400]), - SizedBox(height: 16), - Text( - 'No notifications available.', - style: TextStyle(fontSize: 16, color: Colors.grey), - ), - ], - ), - ) - : ListView.builder( - itemCount: filteredNotifications.length, - itemBuilder: (context, index) { - final notification = filteredNotifications[index]; - return NotificationTile( - title: notification["title"]!, - date: notification["date"]!, - category: notification["category"]!, - ); - }, - ), + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.info_outline, + size: 100, color: Colors.grey[400]), + SizedBox(height: 16), + Text( + 'No notifications available.', + style: + TextStyle(fontSize: 16, color: Colors.grey), + ), + ], + ), + ) + : ListView.builder( + itemCount: filteredNotifications.length, + itemBuilder: (context, index) { + final notification = filteredNotifications[index]; + return NotificationTile( + title: notification['title'] ?? 'No Title', + date: formatDate(notification['created'] ?? ''), + category: notification['category'] ?? 'Unknown', + ); + }, + ), ), ], ), @@ -128,8 +172,11 @@ class TabBarHeader extends StatelessWidget { TextButton( onPressed: () => onTabSelected(index), style: ButtonStyle( - foregroundColor: MaterialStateProperty.resolveWith((states) { - return selectedIndex == index ? Color(0xFF985400) : Colors.grey[700]; + foregroundColor: + MaterialStateProperty.resolveWith((states) { + return selectedIndex == index + ? Color(0xFF985400) + : Colors.grey[700]; }), ), child: Text(text), @@ -169,7 +216,8 @@ class NotificationTile extends StatelessWidget { @override Widget build(BuildContext context) { return ListTile( - leading: Icon(Icons.circle, size: 12, color: category == "Social" ? Colors.red : Colors.grey), + leading: Icon(Icons.circle, + size: 12, color: category == "Social" ? Colors.red : Colors.grey), title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), subtitle: Text(date), ); diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 1b369d46..6f0a366c 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -42,11 +42,11 @@ class BaseScaffold extends ConsumerStatefulWidget { }); final Widget body; final Widget title; - final Widget? navBackArrow; + final Widget? navBackArrow; final Color? dividerColor; final bool showDivider; final bool showBackButton; - final bool colorChange; + final bool colorChange; final bool? mycenterTitle; final List? actions; final Color? bottomColor; @@ -640,7 +640,7 @@ class _BaseScaffoldState extends ConsumerState { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( - title: Padding( + title: Padding( padding: EdgeInsets.only(top: 10), child: Align( alignment: Alignment.centerLeft, @@ -698,9 +698,9 @@ class _BaseScaffoldState extends ConsumerState { ), ], leading: Padding( - padding: const EdgeInsets.only(top: 7.0,left: 4), + padding: const EdgeInsets.only(top: 7.0, left: 4), child: Row( - mainAxisSize:MainAxisSize.min, + mainAxisSize: MainAxisSize.min, children: [ if (widget.showBackButton == true) SizedBox( @@ -721,7 +721,9 @@ class _BaseScaffoldState extends ConsumerState { }, ), ), - SizedBox(width: 7,), + SizedBox( + width: 7, + ), Builder( builder: (BuildContext context) { return SizedBox( @@ -743,8 +745,6 @@ class _BaseScaffoldState extends ConsumerState { ], ), ), - - ), drawer: Drawer( backgroundColor: Colors.white, @@ -826,21 +826,22 @@ class _BaseScaffoldState extends ConsumerState { if (userId != 'guest') ListTile( leading: Icon(Icons.notifications_none), - title: const Text('Notification'), + title: Text(AppLocalizations.of(context)!.notification), onTap: () => _navigateTo(context, '/notification'), ), - ListTile( - leading: Icon(Icons.message_outlined), - // leading: Image.asset( - // DrawerAssetIconPath.feedback, - // color: Colors.black, - // width: 20, - // height: 20, - // ), - // title: const Text('Feedback'), - title: Text(AppLocalizations.of(context)!.feedback_title), - onTap: () => _navigateTo(context, '/feedback', extra: userName), - ), + ListTile( + leading: Icon(Icons.message_outlined), + // leading: Image.asset( + // DrawerAssetIconPath.feedback, + // color: Colors.black, + // width: 20, + // height: 20, + // ), + // title: const Text('Feedback'), + title: Text(AppLocalizations.of(context)!.feedback_title), + onTap: () => + _navigateTo(context, '/feedback', extra: userName), + ), if (role == 'admin') ListTile( leading: Icon(Icons.manage_accounts_outlined), @@ -1014,6 +1015,7 @@ class _BaseScaffoldState extends ConsumerState { body: widget.body, ); } + //drawer close code void _navigateTo(BuildContext context, String route, {Object? extra}) { Navigator.pop(context); // Close the drawer @@ -1051,4 +1053,4 @@ class _BaseScaffoldState extends ConsumerState { break; } } -} \ No newline at end of file +} diff --git a/pubspec.yaml b/pubspec.yaml index 129fb166..b9904725 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.15+16 +version: 1.0.19+20 environment: sdk: ">=3.2.3 <4.0.0"