diff --git a/android/app/build.gradle b/android/app/build.gradle index 2e87a3f1..c1188579 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 = "17" + flutterVersionCode = "20" } def flutterVersionName = localProperties.getProperty("flutter.versionName") if (flutterVersionName == null) { - flutterVersionName = "1.0.16" + 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/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index 5e2dec37..bd464ca9 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -148,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), ), @@ -164,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), ), @@ -194,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), ), @@ -1189,19 +1189,6 @@ class _ChartScreen1State extends ConsumerState { // }); // } - void processCardData(cardData){ - - print('PRocessCardData'); - setState(() { - filteredAndSortedData = (cardData as List) - .where((card) => (card as Map)['is_chart'] == 'false') - .map((card) => card as Map) - .toList() - ..sort((a, b) => (a['order_id'] as int).compareTo(b['order_id'] as int)); - }); - } - - void processChartData(chartsData) { // Group data by 'kpi' Map>> groupedData = {}; @@ -1236,7 +1223,6 @@ class _ChartScreen1State extends ConsumerState { 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; @@ -1244,7 +1230,6 @@ class _ChartScreen1State extends ConsumerState { return orderA.compareTo(orderB); }); - print('Sorted Tabs: $_tabs'); print('Grouped Data: $groupedData'); @@ -1282,10 +1267,8 @@ class _ChartScreen1State extends ConsumerState { cardData = nonChartData; chartScreenData = data['chartScreenData'] ?? {}; - processCardData(cardData); processChartData(chartsData); - print('chartsData :- $chartsData'); print('cardData :- $cardData'); print('chartScreenData :- $chartScreenData'); @@ -1436,17 +1419,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), @@ -1456,11 +1439,10 @@ class _ChartScreen1State extends ConsumerState { 'المرشحات', ), style: TextStyle( - color: Color(0xFF8E8E8E), + color: Color(0xFF8E8E8E), fontSize: 20, fontWeight: FontWeight.w500, fontFamily: 'Roboto', - ), ), ], @@ -1582,7 +1564,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( @@ -1745,8 +1728,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, @@ -1826,8 +1808,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); @@ -1858,14 +1846,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')) { @@ -1888,8 +1874,6 @@ class _ChartScreen1State extends ConsumerState { // return 1.0; // Default fallback (should never be reached) // } - - @override Widget build(BuildContext context) { final locale = ref.watch(localeProvider); @@ -1910,639 +1894,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']?? '#898C81').replaceFirst('#', '0xff'))), - child: Padding( - padding: EdgeInsets.only( - left: 30, right: 30, top: 8, bottom: 5), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - // widget.mainTopic ?? '', - chartScreenData['main_topic'] ?? '', - style: TextStyle( - color: Colors.white, - fontSize: 26, - fontWeight: FontWeight.w400, - fontFamily: 'Roboto' - ), - ), - Container( - width: mywidth / 7, - height: 1.5, - child: Divider( - thickness: 3, - color: Colors.white, - )), - Text( - // widget.title, - chartScreenData['data_set_tile_heading'] ?? '', - style: TextStyle(color: Colors.white, fontSize: 20, - fontWeight: FontWeight.w400, - fontFamily: 'Roboto'), - ), - // 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']?? '#898C81').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 ,), + 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', - 'يشارك', - ), - 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, - ), - ], - ) - ], - ), - SizedBox( - width: 10), // Horizontal space between items - Row( - children: [ - Text( - context.translate( - 'Filter', - 'فلتر', - ), - style: const TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - 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), - ], - ), - ], + 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), - ), - - // Sort and filter the cardData - - itemBuilder: (context, index) { - final item = filteredAndSortedData[index]; - - // print('item'); - // 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 + 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, + ); + }), + ), ), ), - 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( + // 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), + ), - '${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, - ), - ), - // ), + // 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 ), - const SizedBox(height: 5), - Flexible( - fit: FlexFit.loose, - child: FittedBox( - child: Text( - '(${ response[0]['display_value'] ?? 'NA'})', - // '(${data['firstYear'] ?? - // 'NA'} - ${data['lastYear'] ?? - // 'NA'})', + ), + 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: 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), + ), + 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), + ), ), ), ), - ), - ), - ], - ), - ), - )); - } - 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, + 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), + ), ), ), ), - ), - ), - 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']), + Text( + '(${response[1]['display_value'] ?? 'NA'})', + // '(${data['secondLastYear'] ?? 'NA'})', style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.w900, - color: Color(0xFF90B0D5), - ), + fontSize: 9, + fontWeight: + FontWeight.w500, + color: Colors.grey), ), - ), + ], ), - 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), - ), - ], + ), ), - ), - ),); - } - - - }, - ), - ), - // 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])), - ], + ); + } + }, ), ), - ); - }, + // 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])), + ], + ), + ), + ); + }, + ), + ], + ), ), - ], - ), - ), - ), + ), + ), + ], ), - ], - ), - ), - ),); + ), + ), + ); } Widget _buildArrowButton( @@ -2599,4 +2647,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 5ed4864c..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( @@ -307,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, @@ -522,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( @@ -624,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( @@ -631,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(), @@ -735,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( @@ -742,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(), @@ -753,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, ), ), ), @@ -781,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( @@ -888,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( @@ -1019,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( @@ -1224,6 +1297,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( @@ -1790,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 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 b826fa2e..7ca1855d 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'); @@ -337,6 +348,7 @@ class _ManageUserRouterState extends State { image: ExactAssetImage(MiscIconAssetPath.search), width: 24, height: 24, + color: Color(0xFFAA8E83) ), @@ -348,10 +360,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 90d5a899..0b172de0 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, @@ -824,21 +824,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), @@ -1012,6 +1013,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 @@ -1049,4 +1051,4 @@ class _BaseScaffoldState extends ConsumerState { break; } } -} \ No newline at end of file +} diff --git a/pubspec.yaml b/pubspec.yaml index 215e91b2..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.16+17 +version: 1.0.19+20 environment: sdk: ">=3.2.3 <4.0.0"