From e6a2d60f0997e6ddf8cfb4b45e072877bd607b1c Mon Sep 17 00:00:00 2001 From: venbaittech Date: Thu, 21 Aug 2025 15:49:34 +0530 Subject: [PATCH] FIX-PIE-BAR CHART CHANGES --- .../UAE_Numbers/uae_numbers.dart | 130 +- .../auth_verification/changepassword.dart | 17 +- .../auth_verification/create_new_pw.dart | 58 +- .../auth_verification/forgot_password.dart | 82 +- .../Screens/charts/screens/chart_screen.dart | 523 +++--- .../Screens/charts/widgets/chart_widget.dart | 1516 +++++++++-------- lib/presentation/components/dialogs.dart | 42 +- .../routes/auth_routes/login_route.dart | 78 +- .../tab_routes/home_route.dart | 78 +- .../Drawer Items/manage_users.dart | 626 +++---- .../notification/notification_details.dart | 9 +- .../drawer_routes/profile/profile_route.dart | 2 +- 12 files changed, 1691 insertions(+), 1470 deletions(-) diff --git a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart index 2e97988a..e4dba63c 100644 --- a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart +++ b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart @@ -247,7 +247,7 @@ class _UaenumberWidgetState extends ConsumerState { if (isLoading) { return Container( - color: Color(0x98FFFCE5), + color: isDarkTheme ? Colors.black : Colors.white, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -291,7 +291,7 @@ class _UaenumberWidgetState extends ConsumerState { hintText: AppLocalizations.of(context)!.search, hintStyle: TextStyle( color: - isDarkTheme ? Color(0xFF898C81) : Color(0xFF898C81), + isDarkTheme ? Color(0xFF898C81) : Color(0xFF898C81), fontFamily: context.translate('Roboto', 'NotoKufi'), fontSize: 18, // height: 1.8, @@ -314,16 +314,16 @@ class _UaenumberWidgetState extends ConsumerState { ), suffixIcon: _searchController.text.isNotEmpty ? IconButton( - icon: Icon( - Icons.clear, - color: Color(0xFFAA8E83), - size: 18, - ), - onPressed: () { - _searchController.clear(); - filterData(''); - }, - ) + icon: Icon( + Icons.clear, + color: Color(0xFFAA8E83), + size: 18, + ), + onPressed: () { + _searchController.clear(); + filterData(''); + }, + ) : null, // contentPadding: EdgeInsets.symmetric(vertical: 12, horizontal: 18.0), border: InputBorder.none, @@ -339,38 +339,38 @@ class _UaenumberWidgetState extends ConsumerState { child: filteredData.isEmpty ? Center(child: Text("No data available")) : ListView( - children: [ - ...filteredData.map((mainTopic) { - String colorPattern = mainTopic['color_pattern']; - Color backgroundColor = - Color(int.parse(colorPattern)); - Color borderColor = backgroundColor; - int index = filteredData.indexOf(mainTopic); + children: [ + ...filteredData.map((mainTopic) { + String colorPattern = mainTopic['color_pattern']; + Color backgroundColor = + Color(int.parse(colorPattern)); + Color borderColor = backgroundColor; + int index = filteredData.indexOf(mainTopic); - return CustomExpandableTile( - index: index, - isExpanded: expandedIndex == index, - onTap: (index) { - setState(() { - expandedIndex = - (expandedIndex == index) ? null : index; - }); - }, - title: mainTopic['main_topic'], - titleBackgroundColor: backgroundColor, - // currentTheme: currentTheme, - children: _buildSubTopics( - mainTopic['sub_topics'] ?? [], - mywidth, - myheight, - borderColor, - colorPattern, - mainTopic['main_topic'], - isDarkTheme), - ); - }), - ], - ), + return CustomExpandableTile( + index: index, + isExpanded: expandedIndex == index, + onTap: (index) { + setState(() { + expandedIndex = + (expandedIndex == index) ? null : index; + }); + }, + title: mainTopic['main_topic'], + titleBackgroundColor: backgroundColor, + // currentTheme: currentTheme, + children: _buildSubTopics( + mainTopic['sub_topics'] ?? [], + mywidth, + myheight, + borderColor, + colorPattern, + mainTopic['main_topic'], + isDarkTheme), + ); + }), + ], + ), ), ], ), @@ -390,13 +390,13 @@ class _UaenumberWidgetState extends ConsumerState { return subTopics .map((subTopic) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - buildCategoryTitle(subTopic['sub_topic'], isDarkTheme), - ..._buildDataSetCards(subTopic['tile_data'] ?? [], myWidth, - borderColor, colorPattern, mainTopic), - ], - )) + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildCategoryTitle(subTopic['sub_topic'], isDarkTheme), + ..._buildDataSetCards(subTopic['tile_data'] ?? [], myWidth, + borderColor, colorPattern, mainTopic), + ], + )) .toList(); } @@ -417,7 +417,7 @@ class _UaenumberWidgetState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: rowItems.map((data) { final cardWidth = - rowItems.length == 1 ? myWidth : (myWidth - 18) / 1.6; + rowItems.length == 1 ? myWidth : (myWidth - 18) / 1.6; return Expanded( child: Padding( @@ -665,19 +665,19 @@ class _CustomExpandableTileState extends ConsumerState { height: widget.isExpanded ? myheight * 0.52 : 0, child: widget.isExpanded ? SingleChildScrollView( - child: Container( - decoration: BoxDecoration( - color: isDarkTheme - ? Color(0xFF000000) - : Color(0xFFFFFFFF), - // borderRadius: BorderRadius.all(Radius.circular(20)) - ), - padding: const EdgeInsets.all(1), - child: Column( - children: widget.children, - ), - ), - ) + child: Container( + decoration: BoxDecoration( + color: isDarkTheme + ? Color(0xFF000000) + : Color(0xFFFFFFFF), + // borderRadius: BorderRadius.all(Radius.circular(20)) + ), + padding: const EdgeInsets.all(1), + child: Column( + children: widget.children, + ), + ), + ) : null, ), ), @@ -685,4 +685,4 @@ class _CustomExpandableTileState extends ConsumerState { ), ); } -} \ No newline at end of file +} diff --git a/lib/presentation/Screens/auth_verification/changepassword.dart b/lib/presentation/Screens/auth_verification/changepassword.dart index c23170e8..2f652e48 100644 --- a/lib/presentation/Screens/auth_verification/changepassword.dart +++ b/lib/presentation/Screens/auth_verification/changepassword.dart @@ -63,8 +63,7 @@ class _ResetPasswordScreenState extends State { // Proceed with OTP request final otpResponse = await http.post( - Uri.parse( - '$apiUrl/api/collections/otp_requests/records'), + Uri.parse('$apiUrl/api/collections/otp_requests/records'), headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer $authToken', @@ -260,12 +259,14 @@ class _ResetPasswordScreenState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ if (_isLoading) - const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - color: Colors.white, - strokeWidth: 2, + Container( + child: const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2, + ), ), ) else ...[ diff --git a/lib/presentation/Screens/auth_verification/create_new_pw.dart b/lib/presentation/Screens/auth_verification/create_new_pw.dart index 9ccc10df..92d12609 100644 --- a/lib/presentation/Screens/auth_verification/create_new_pw.dart +++ b/lib/presentation/Screens/auth_verification/create_new_pw.dart @@ -26,9 +26,9 @@ class CreateNewPw extends ConsumerStatefulWidget { const CreateNewPw( {Key? key, - required this.userId, - required this.email, - required this.keyParam}); + required this.userId, + required this.email, + required this.keyParam}); @override ConsumerState createState() => _CreateNewPwState(); @@ -125,7 +125,7 @@ class _CreateNewPwState extends ConsumerState { try { // Attempt to authenticate the user with email and password final authResponse = - await _pb.collection('users').authWithPassword(email, password); + await _pb.collection('users').authWithPassword(email, password); if (authResponse != null) { print('Password match successful for email: $email'); @@ -155,20 +155,20 @@ class _CreateNewPwState extends ConsumerState { }; bool isPasswordValid = - await verifyUserPassword(widget.email, oldPassword); + await verifyUserPassword(widget.email, oldPassword); print(isPasswordValid); if (isPasswordValid) { // Update password await _pb.collection('users').update( - userId, - body: { - 'password': newPassword, - 'passwordConfirm': newPassword, - }, - headers: headers, - ); + userId, + body: { + 'password': newPassword, + 'passwordConfirm': newPassword, + }, + headers: headers, + ); setState(() { isLoading = false; @@ -181,9 +181,9 @@ class _CreateNewPwState extends ConsumerState { AppLocalizations.of(context)!.password_update_successfully, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), ), ); @@ -206,9 +206,9 @@ class _CreateNewPwState extends ConsumerState { AppLocalizations.of(context)!.your_old_password_incorrect, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), backgroundColor: Colors.red, ), @@ -226,9 +226,9 @@ class _CreateNewPwState extends ConsumerState { 'Failed to update password: $e', 'فشل في تحديث كلمة المرور'), style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), backgroundColor: Colors.red, ), @@ -274,13 +274,15 @@ class _CreateNewPwState extends ConsumerState { child: SafeArea( child: _isPasswordUpdated ? _buildSuccessContent( - screenHeight, screenWidth, isDarkTheme) + screenHeight, screenWidth, isDarkTheme) : _buildPasswordForm(ref, screenHeight, screenWidth), ), ), if (isLoading) Container( - color: Color(0x98FFFCE5), // Semi-transparent background + color: isDarkTheme + ? Colors.black + : Colors.white, // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -290,7 +292,7 @@ class _CreateNewPwState extends ConsumerState { child: LinearProgressIndicator( minHeight: 5, // Adjust thickness backgroundColor: - Colors.grey[100], // Optional: Background color + Colors.grey[100], // Optional: Background color valueColor: AlwaysStoppedAnimation( Color(0xFFAA8E83)), // Loader color ), @@ -403,7 +405,7 @@ class _CreateNewPwState extends ConsumerState { 'NotoKufi', ), fontSize: - passwordLocale?.languageCode == 'ar' ? 14 : 15, + passwordLocale?.languageCode == 'ar' ? 14 : 15, fontWeight: FontWeight.w700, color: Color(0xFF898C81)), ), @@ -416,7 +418,7 @@ class _CreateNewPwState extends ConsumerState { 'NotoKufi', ), fontSize: - passwordLocale?.languageCode == 'ar' ? 14 : 15, + passwordLocale?.languageCode == 'ar' ? 14 : 15, color: Color(0xFF898C81), fontWeight: FontWeight.w700), ), @@ -721,7 +723,7 @@ class _CreateNewPwState extends ConsumerState { 'NotoKufi', ), fontSize: - passwordLocale?.languageCode == 'ar' ? 14 : 18, + passwordLocale?.languageCode == 'ar' ? 14 : 18, color: Colors.white), ), SizedBox(width: 2), @@ -854,4 +856,4 @@ class _CreateNewPwState extends ConsumerState { ), ); } -} \ No newline at end of file +} diff --git a/lib/presentation/Screens/auth_verification/forgot_password.dart b/lib/presentation/Screens/auth_verification/forgot_password.dart index 862e50be..0d0a934e 100644 --- a/lib/presentation/Screens/auth_verification/forgot_password.dart +++ b/lib/presentation/Screens/auth_verification/forgot_password.dart @@ -7,6 +7,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/my_router.dart'; +import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; @@ -191,13 +192,14 @@ class _ForgotPasswordState extends ConsumerState { // throw Exception("User not found"); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('User not found', + content: Text( + 'User not found', style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ),), + 'Roboto', + 'NotoKufi', + )), + ), backgroundColor: Colors.red, ), ); @@ -222,15 +224,14 @@ class _ForgotPasswordState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: - Text(AppLocalizations.of(context)!.password_update_successfully, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), - ), + content: Text( + AppLocalizations.of(context)!.password_update_successfully, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + ), backgroundColor: Colors.green, ), ); @@ -243,13 +244,13 @@ class _ForgotPasswordState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('Failed to update password: $e', + content: Text( + 'Failed to update password: $e', style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + 'Roboto', + 'NotoKufi', + )), ), backgroundColor: Colors.red, ), @@ -277,6 +278,12 @@ class _ForgotPasswordState extends ConsumerState { } }); + // final themeMode = ref.read(themeProvider); + // final themeMode = ThemeMode.dark; + final isDarkTheme = ref.read(themeProvider) == ThemeMode.dark || + (ref.read(themeProvider) == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + return Scaffold( backgroundColor: Colors.white, body: Stack(children: [ @@ -289,7 +296,9 @@ class _ForgotPasswordState extends ConsumerState { ), if (isLoading) Container( - color: Color(0x98FFFCE5), // Semi-transparent background + color: isDarkTheme + ? Colors.black + : Colors.white, // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -386,7 +395,6 @@ class _ForgotPasswordState extends ConsumerState { 'NotoKufi', ), fontWeight: FontWeight.w300, - ), ), SizedBox(height: 10), @@ -404,11 +412,10 @@ class _ForgotPasswordState extends ConsumerState { passwordLocale?.languageCode == 'ar' ? 14 : 15, fontWeight: FontWeight.w700, color: Color(0xFF898C81), - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - ), + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), ), TextSpan( text: context.translate('from Previously Used Password', @@ -435,8 +442,8 @@ class _ForgotPasswordState extends ConsumerState { hintText: AppLocalizations.of(context)!.enter_new_password, // prefixIcon: Icon(Icons.lock, color: Colors.blue), hintStyle: TextStyle( - color: Color(0xFFC3C6CB), - fontWeight: FontWeight.w400, + color: Color(0xFFC3C6CB), + fontWeight: FontWeight.w400, fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -518,8 +525,8 @@ class _ForgotPasswordState extends ConsumerState { // hintText: 'Confirm new password', hintText: AppLocalizations.of(context)!.confirm_new_password, hintStyle: TextStyle( - color: Color(0xFFC3C6CB), - fontWeight: FontWeight.w400, + color: Color(0xFFC3C6CB), + fontWeight: FontWeight.w400, fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -629,11 +636,7 @@ class _ForgotPasswordState extends ConsumerState { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), - - - + )), ), SizedBox(width: 2), Icon( @@ -681,14 +684,13 @@ class _ForgotPasswordState extends ConsumerState { AppLocalizations.of(context)!.password_changed_successfully, textAlign: TextAlign.center, style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF414042), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Color(0xFF414042), fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), SizedBox(height: 20), ElevatedButton( diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index 6fc555de..aba69d31 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -122,7 +122,7 @@ class _ChartScreen1State extends ConsumerState { final themeMode = (isDark ? 'dark' : 'light'); fetchChartData(widget.dataSets, locale?.languageCode ?? 'en', widget.kpi, - widget.filter_data, themeMode) + widget.filter_data, themeMode) .then((_) { if (_tabsData.isNotEmpty) { // Call onTabSelected for the first tab @@ -196,9 +196,9 @@ class _ChartScreen1State extends ConsumerState { AppLocalizations.of(context)!.added_to_Bookmark, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), duration: Duration(seconds: 2), ), @@ -212,9 +212,9 @@ class _ChartScreen1State extends ConsumerState { AppLocalizations.of(context)!.failed_To_Remove, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), // backgroundColor: Color(0xFFEB5F24), duration: Duration(seconds: 2), @@ -247,9 +247,9 @@ class _ChartScreen1State extends ConsumerState { AppLocalizations.of(context)!.removed_from_Bookmark, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), duration: Duration(seconds: 2), ), @@ -263,9 +263,9 @@ class _ChartScreen1State extends ConsumerState { 'Failed to Remove', style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), // backgroundColor: Color(0xFFEB5F24), duration: Duration(seconds: 2), @@ -364,7 +364,7 @@ class _ChartScreen1State extends ConsumerState { foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(10.0), // Set text color + BorderRadius.circular(10.0), // Set text color ), ), child: Text( @@ -475,7 +475,7 @@ class _ChartScreen1State extends ConsumerState { foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(10.0), // Set text color + BorderRadius.circular(10.0), // Set text color ), ), child: Text( @@ -514,7 +514,7 @@ class _ChartScreen1State extends ConsumerState { Future _getWidget() async { await Future.delayed(Duration(milliseconds: 50)); // Ensures widget is built final RenderBox? box = - cardKey.currentContext?.findRenderObject() as RenderBox?; + cardKey.currentContext?.findRenderObject() as RenderBox?; if (box != null) { final Offset position = box.localToGlobal(Offset.zero); @@ -705,7 +705,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -736,7 +736,7 @@ class _ChartScreen1State extends ConsumerState { .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } else { @@ -1223,11 +1223,11 @@ class _ChartScreen1State extends ConsumerState { } else { ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } @@ -1257,11 +1257,11 @@ class _ChartScreen1State extends ConsumerState { if (locale.languageCode == 'ar') { ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = true; ref .read(previousHomeTourProvider - .notifier) + .notifier) .state = false; tutorialCoachMark.finish(); } else { @@ -1396,8 +1396,8 @@ class _ChartScreen1State extends ConsumerState { String formattedKpi = kpi .split('_') // Split by underscore .map((word) => word.isNotEmpty - ? word[0].toUpperCase() + word.substring(1) - : '') // Capitalize + ? word[0].toUpperCase() + word.substring(1) + : '') // Capitalize .join(' '); // Join words with space return {'id': kpi, 'name': tabHeading, 'order': tabOrder.toString()}; }).toList(); @@ -1435,7 +1435,7 @@ class _ChartScreen1State extends ConsumerState { selectedFiltersApi = filter_data.map>((entry) { if (entry is Map) { return entry.map( - (key, value) => MapEntry(key.toString(), value)); + (key, value) => MapEntry(key.toString(), value)); } return {}; }).toList(); @@ -1503,12 +1503,12 @@ class _ChartScreen1State extends ConsumerState { // Transform the selectedFilters list into the required format formattedFilters = selectedFilters - // .where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty) + // .where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty) .map((filter) { return { 'filter_key': filter['filter_key'], 'filter_data': - filter['filter_data'].map((item) => item.toString()).toList() + filter['filter_data'].map((item) => item.toString()).toList() }; }).toList(); @@ -1516,7 +1516,7 @@ class _ChartScreen1State extends ConsumerState { // Convert to JSON format String selectedFormatFilters = - jsonEncode({'kpi': tabWiseKpi, 'filter_data': formattedFilters}); + jsonEncode({'kpi': tabWiseKpi, 'filter_data': formattedFilters}); print('Formatted Filters2: $selectedFormatFilters'); final locale = ref.watch(localeProvider)?.languageCode ?? 'en'; @@ -1599,8 +1599,8 @@ class _ChartScreen1State extends ConsumerState { if (kDebugMode) { print( "Selected year: ${selectedFilters.firstWhere((f) => f['filter_key'] == 'TIME_PERIOD', orElse: () => { - 'filter_data': ['Unknown'] - })['filter_data']} - No data for chart: : $chartHeading"); + 'filter_data': ['Unknown'] + })['filter_data']} - No data for chart: : $chartHeading"); } // Add the complete chart data to the filteredData list @@ -1686,11 +1686,11 @@ class _ChartScreen1State extends ConsumerState { // Initialize selected filters structure from the stored value, if exists List> selectedFilters = - selectedFiltersStorage.isNotEmpty - ? List.from(selectedFiltersStorage) // Use stored filters - : filters.map((filter) { - return {"filter_key": filter["filter_key"], "filter_data": []}; - }).toList(); // Or initialize empty filters + selectedFiltersStorage.isNotEmpty + ? List.from(selectedFiltersStorage) // Use stored filters + : filters.map((filter) { + return {"filter_key": filter["filter_key"], "filter_data": []}; + }).toList(); // Or initialize empty filters print('selectedFiltersStoragedrgt- $selectedFiltersStorage'); @@ -1769,7 +1769,7 @@ class _ChartScreen1State extends ConsumerState { final filterKey = filter["filter_key"]; final filterData = filter["filter_data"]; final filter_text_and_order = - filter["filter_text_and_order"]; + filter["filter_text_and_order"]; final fieldOrder = filter_text_and_order['order']; return StatefulBuilder( @@ -1808,7 +1808,7 @@ class _ChartScreen1State extends ConsumerState { return StatefulBuilder( builder: (context, dialogSetState) { final locale = - ref.watch(localeProvider); + ref.watch(localeProvider); print('localelocale $locale'); return AlertDialog( @@ -1817,10 +1817,10 @@ class _ChartScreen1State extends ConsumerState { "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", style: TextStyle( fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - )), + context.translate( + 'Roboto', + 'NotoKufi', + )), ), content: SingleChildScrollView( child: ListBody( @@ -1832,12 +1832,12 @@ class _ChartScreen1State extends ConsumerState { style: TextStyle( fontFamily: context .translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), value: selectedFilter[ - "filter_data"] + "filter_data"] .contains(value), onChanged: (bool? isChecked) { @@ -1845,11 +1845,11 @@ class _ChartScreen1State extends ConsumerState { if (isChecked == true) { selectedFilter[ - "filter_data"] + "filter_data"] .add(value); } else { selectedFilter[ - "filter_data"] + "filter_data"] .remove(value); } }); @@ -1872,7 +1872,7 @@ class _ChartScreen1State extends ConsumerState { ), style: TextStyle( fontFamily: - context.translate( + context.translate( 'Roboto', 'NotoKufi', ), @@ -1895,51 +1895,51 @@ class _ChartScreen1State extends ConsumerState { horizontal: 16.0, vertical: 12.0), decoration: BoxDecoration( border: - Border.all(color: Color(0xFF7296BE)), + Border.all(color: Color(0xFF7296BE)), borderRadius: BorderRadius.circular(8.0), ), child: Wrap( spacing: 8.0, runSpacing: 4.0, children: selectedFilter["filter_data"] - .isEmpty + .isEmpty ? [ - Text( - // "${locale == 'ar' ? 'يختار ' : 'Select '}" - "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", - style: TextStyle( - color: isDarkTheme - ? Color(0xFFFFFFFF) - : Colors.grey, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - ), - ) - ] + Text( + // "${locale == 'ar' ? 'يختار ' : 'Select '}" + "${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}", + style: TextStyle( + color: isDarkTheme + ? Color(0xFFFFFFFF) + : Colors.grey, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), + ) + ] : selectedFilter["filter_data"] - .map((value) { - return Chip( - label: Text( - value, - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - )), - ), - // backgroundColor: Colors.white, // Default background color - onDeleted: () { - setState(() { - selectedFilter[ - "filter_data"] - .remove(value); - }); - }, - ); - }).toList(), + .map((value) { + return Chip( + label: Text( + value, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + // backgroundColor: Colors.white, // Default background color + onDeleted: () { + setState(() { + selectedFilter[ + "filter_data"] + .remove(value); + }); + }, + ); + }).toList(), ), ), ), @@ -1976,7 +1976,8 @@ class _ChartScreen1State extends ConsumerState { ref.watch(localeProvider)?.languageCode ?? 'en'; print('locale22- $locale'); - final isDark = ref.watch(themeProvider) == ThemeMode.dark || + final isDark = ref.watch(themeProvider) == + ThemeMode.dark || (ref.watch(themeProvider) == ThemeMode.system && MediaQuery.of(context).platformBrightness == Brightness.dark); @@ -2015,7 +2016,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -2029,7 +2030,7 @@ class _ChartScreen1State extends ConsumerState { "Selected Filters before applying: $selectedFilters"); if (selectedFilters.every( - (filter) => filter['filter_data'].isEmpty)) { + (filter) => filter['filter_data'].isEmpty)) { setState(() { isLoading = true; }); @@ -2048,11 +2049,13 @@ class _ChartScreen1State extends ConsumerState { 'en'; print('locale22- $locale'); - final isDark = ref.watch(themeProvider) == ThemeMode.dark || - (ref.watch(themeProvider) == ThemeMode.system && - MediaQuery.of(context) - .platformBrightness == - Brightness.dark); + final isDark = + ref.watch(themeProvider) == ThemeMode.dark || + (ref.watch(themeProvider) == + ThemeMode.system && + MediaQuery.of(context) + .platformBrightness == + Brightness.dark); final themeMode = (isDark ? 'dark' : 'light'); fetchChartData( @@ -2099,7 +2102,7 @@ class _ChartScreen1State extends ConsumerState { fontWeight: FontWeight.bold, ), overflow: - TextOverflow.ellipsis, // Prevents wrapping + TextOverflow.ellipsis, // Prevents wrapping maxLines: 1, // Ensures single line ), ), @@ -2275,7 +2278,7 @@ class _ChartScreen1State extends ConsumerState { double calculateAspectRatio(int crossAxisCount, List cardData) { // Determine a default aspect ratio based on the most common chart type in the list if (cardData.any((item) => - item['chart_type'] == 'total' || item['chart_type'] == 'average')) { + item['chart_type'] == 'total' || item['chart_type'] == 'average')) { // return crossAxisCount == 1 ? 0.2 : (crossAxisCount > 2 ? 0.9 : 0.7); return crossAxisCount == 2 ? 1.0 : 0.7; // Larger Content // return crossAxisCount == 2 ? 1.5 : 0.9; @@ -2310,7 +2313,7 @@ class _ChartScreen1State extends ConsumerState { ); final Uint8List? capturedImage = - await screenshotController.captureFromWidget( + await screenshotController.captureFromWidget( Material(child: svgWidget), ); @@ -2414,7 +2417,7 @@ class _ChartScreen1State extends ConsumerState { widget.filter_data ?? []; final String safeKpi = widget.kpi ?? ''; fetchChartData( - widget.dataSets, localeCode, safeKpi, safeFilterData, themeString) + widget.dataSets, localeCode, safeKpi, safeFilterData, themeString) .then((_) { print('DEBUG KPI: $safeKpi'); @@ -2461,7 +2464,7 @@ class _ChartScreen1State extends ConsumerState { /// 🔥 Call your API fetchChartData( - widget.dataSets, localeCode, safeKpi, safeFilterData, themeString) + widget.dataSets, localeCode, safeKpi, safeFilterData, themeString) .then((_) { print('DEBUG KPI: $safeKpi'); print('TAB11: $currentTab'); @@ -2486,10 +2489,10 @@ class _ChartScreen1State extends ConsumerState { mainTopic = chartScreenData['main_topic'] ?? ''; int crossAxisCount = - cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1; + cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1; final color = - Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); + Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); // Color bodyColor = Color( // int.parse( // (chartScreenData['body_color'] ?? '#898C81') @@ -2501,7 +2504,8 @@ class _ChartScreen1State extends ConsumerState { // final bodyColor = Color( int.parse( - (chartScreenData['header_color'] ?? '#898C81').replaceFirst('#', '0xff'), + (chartScreenData['header_color'] ?? '#898C81') + .replaceFirst('#', '0xff'), ), ); final chartHeader = chartScreenData['main_topic'] ?? ''; @@ -2526,31 +2530,31 @@ class _ChartScreen1State extends ConsumerState { key: _scaffoldKey, title: (pageTitle == 'home') ? Text( - AppLocalizations.of(context)!.nav_home, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF000000), - ), - ) + AppLocalizations.of(context)!.nav_home, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF000000), + ), + ) : Text( - context.translate( - 'UAE Numbers', - 'أرقام الإمارات', - ), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', + context.translate( + 'UAE Numbers', + 'أرقام الإمارات', + ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF000000), + ), ), - color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF000000), - ), - ), // appbarColor: Color(int.parse(widget.bgColor)), // Example color appbarColor: - isDarkTheme ? Colors.black : Colors.white, // Example color + isDarkTheme ? Colors.black : Colors.white, // Example color // appbarColor: Color(int.parse( // (chartScreenData['header_color'] ?? '#ffffff') // .replaceFirst('#', '0xff'))), @@ -2566,7 +2570,7 @@ class _ChartScreen1State extends ConsumerState { child: Column( children: [ Container( - // height: myheight / 5, + // height: myheight / 5, width: double.infinity, // color: color, @@ -2584,7 +2588,7 @@ class _ChartScreen1State extends ConsumerState { decoration: BoxDecoration( color: Color(int.parse( (chartScreenData['header_color'] ?? - '#898C81') + '#898C81') .replaceFirst('#', '0xff'))), borderRadius: BorderRadius.only( topLeft: Radius.circular(20), @@ -2668,8 +2672,8 @@ class _ChartScreen1State extends ConsumerState { color: isBookmarked ? isDarkTheme - ? Colors.white.withAlpha(90) - : Colors.grey.shade200 + ? Colors.white.withAlpha(90) + : Colors.grey.shade200 : null, // Background color borderRadius: BorderRadius.circular( 8), // Curved corners @@ -2678,47 +2682,47 @@ class _ChartScreen1State extends ConsumerState { children: [ isBookmarked ? Text( - context.translate( - 'Bookmarked', - 'إشارة مرجعية', - ), - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: isDarkTheme - ? Colors.grey - : Color(0xFF416587), - // color: Color(int.parse( - // (chartScreenData[ - // 'body_color'] ?? - // '#898C81') - // .replaceFirst( - // '#', '0xff'))), - ), - ) + context.translate( + 'Bookmarked', + 'إشارة مرجعية', + ), + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500, + color: isDarkTheme + ? Colors.grey + : Color(0xFF416587), + // color: Color(int.parse( + // (chartScreenData[ + // 'body_color'] ?? + // '#898C81') + // .replaceFirst( + // '#', '0xff'))), + ), + ) : Text( - context.translate( - 'Bookmark', - 'إشارة مرجعية', - ), - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w500, - color: isDarkTheme - ? Colors.grey - : Color(0xFF416587), - ), - ), + context.translate( + 'Bookmark', + 'إشارة مرجعية', + ), + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w500, + color: isDarkTheme + ? Colors.grey + : Color(0xFF416587), + ), + ), SizedBox(width: 5), // Text( @@ -2746,11 +2750,11 @@ class _ChartScreen1State extends ConsumerState { color: isBookmarked ? isDarkTheme - ? Colors.grey - : Color(0xFF416587) + ? Colors.grey + : Color(0xFF416587) : isDarkTheme - ? Colors.grey - : Color(0xFF416587), + ? Colors.grey + : Color(0xFF416587), // color: isBookmarked // ? Color(int.parse( // (chartScreenData[ @@ -2760,8 +2764,6 @@ class _ChartScreen1State extends ConsumerState { // '#', '0xff'))) // : Colors.white, ), - - ], ), ), @@ -2794,21 +2796,27 @@ class _ChartScreen1State extends ConsumerState { SizedBox(width: 5), _isSharing ? SizedBox( - width: 24, - height: 24, - child: - CircularProgressIndicator( - color: Colors.white, - strokeWidth: 2, - ), - ) // Show loading spinner + width: 24, + height: 24, + child: + CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2, + ), + ) // Show loading spinner : Image( - image: AssetImage( - isDarkTheme ? UaeNumbersAssetPath.shareDark : UaeNumbersAssetPath.shareLight, - ), - width: 24, // Set your desired width - height: 24, // Set your desired height - ) + image: AssetImage( + isDarkTheme + ? UaeNumbersAssetPath + .shareDark + : UaeNumbersAssetPath + .shareLight, + ), + width: + 24, // Set your desired width + height: + 24, // Set your desired height + ) ], ), ), @@ -2869,7 +2877,6 @@ class _ChartScreen1State extends ConsumerState { // context, filterData, chartsData); // }, // ), - ], ), SizedBox(width: 10), @@ -2885,11 +2892,11 @@ class _ChartScreen1State extends ConsumerState { color: isDarkTheme ? Color(int.parse( - (chartScreenData['body_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))) + (chartScreenData['body_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))) : Color(int.parse( - (chartScreenData['body_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))), + (chartScreenData['body_color'] ?? '#898C81') + .replaceFirst('#', '0xff'))), // color: Color(int.parse( // (chartScreenData['body_color'] ?? '#898C81') @@ -2922,7 +2929,7 @@ class _ChartScreen1State extends ConsumerState { return _buildTab( _tabsData[index], isActive: - index == _activeTabIndex, + index == _activeTabIndex, ); }), ), @@ -2932,9 +2939,9 @@ class _ChartScreen1State extends ConsumerState { if (_tabsData.length > 1) _buildArrowButton( onPressed: - _activeTabIndex < _tabsData.length - 1 - ? _scrollRight - : null, + _activeTabIndex < _tabsData.length - 1 + ? _scrollRight + : null, icon: Icons.arrow_forward_ios, ), ], @@ -2969,7 +2976,7 @@ class _ChartScreen1State extends ConsumerState { child: CardWidget( card: card, chartScreenData: - chartScreenData, + chartScreenData, themeMode: themeMode)), ], )); @@ -2978,7 +2985,7 @@ class _ChartScreen1State extends ConsumerState { child: CardWidget( card: card, chartScreenData: - chartScreenData, + chartScreenData, themeMode: themeMode))); if (tempRow.length == 2) { rows.add(Row(children: tempRow)); @@ -3008,7 +3015,7 @@ class _ChartScreen1State extends ConsumerState { themeMode == ThemeMode.dark || (themeMode == ThemeMode.system && MediaQuery.of(context) - .platformBrightness == + .platformBrightness == Brightness.dark); // final Map mainTopicColors = { @@ -3018,11 +3025,11 @@ class _ChartScreen1State extends ConsumerState { // }; final String mainTopic = - chartScreenData['main_topic']; + chartScreenData['main_topic']; final Color backgroundColor = Color(int.parse( (chartScreenData['body_color'] ?? - '#898C81') + '#898C81') .replaceFirst('#', '0xff'))); // final Color backgroundColor = isDarkTheme @@ -3039,8 +3046,8 @@ class _ChartScreen1State extends ConsumerState { color: Color( int.parse( (chartScreenData[ - 'border_color'] ?? - '#898C81') + 'border_color'] ?? + '#898C81') .replaceFirst('#', '0xff'), ), ), // Border color @@ -3054,21 +3061,21 @@ class _ChartScreen1State extends ConsumerState { padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: - CrossAxisAlignment.start, + CrossAxisAlignment.start, children: [ // ConstrainedBox Container( height: (chartsData[index][ - 'chart_height'] == - null || - chartsData[index][ - 'chart_height'] == - 0) + 'chart_height'] == + null || + chartsData[index][ + 'chart_height'] == + 0) ? 350 : double.tryParse( - chartsData[index] - ['chart_height'] - .toString()), + chartsData[index] + ['chart_height'] + .toString()), // height: (chartsData[index] // ['chart_type'] == // 'pie_chart') @@ -3091,7 +3098,7 @@ class _ChartScreen1State extends ConsumerState { // child: buildChart(chartsData[index]), child: ChartWidget( chartData: - chartsData[index], + chartsData[index], bodyColor: bodyColor, chartHeader: chartHeader, isDarkTheme: isDarkTheme), @@ -3119,25 +3126,28 @@ class _ChartScreen1State extends ConsumerState { color: isDarkTheme ? Colors.transparent : Color(int.parse( - (chartScreenData['header_color'] ?? '#898C81') - .replaceFirst( - '#', '0xff'))), // Semi-transparent background - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.symmetric( - horizontal: 40), // Left & Right space - child: LinearProgressIndicator( - minHeight: 5, // Adjust thickness - backgroundColor: isDarkTheme - ? Colors.transparent - : Colors.grey[100], // Optional: Background color - valueColor: AlwaysStoppedAnimation( - Color(0xFFAA8E83)), // Loader color + (chartScreenData['header_color'] ?? '#898C81') + .replaceFirst( + '#', '0xff'))), // Semi-transparent background + child: Container( + color: isDarkTheme ? Colors.black : Colors.white, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.symmetric( + horizontal: 40), // Left & Right space + child: LinearProgressIndicator( + minHeight: 5, // Adjust thickness + backgroundColor: isDarkTheme + ? Colors.transparent + : Colors.grey[100], // Optional: Background color + valueColor: AlwaysStoppedAnimation( + Color(0xFFAA8E83)), // Loader color + ), ), - ), - ], + ], + ), ), ) ])), @@ -3147,7 +3157,7 @@ class _ChartScreen1State extends ConsumerState { Widget _buildArrowButton( {required VoidCallback? onPressed, required IconData icon}) { final color = - Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); + Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16)); return Container( margin: EdgeInsets.symmetric(horizontal: 5.0), width: 25.0, // Set the width of the circle @@ -3156,10 +3166,10 @@ class _ChartScreen1State extends ConsumerState { // color: onPressed == null ? Colors.grey[400] : Colors.white, color: onPressed != null ? Color(int.parse((chartScreenData['header_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))) + .replaceFirst('#', '0xff'))) : isDarkTheme - ? Colors.grey[700] - : Colors.grey[200], + ? Colors.grey[700] + : Colors.grey[200], shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(5.0), // boxShadow: [ @@ -3170,7 +3180,8 @@ class _ChartScreen1State extends ConsumerState { // ), // ], ), - child: Center( // ✅ Center the IconButton + child: Center( + // ✅ Center the IconButton child: IconButton( padding: EdgeInsets.zero, // ✅ Remove default padding constraints: BoxConstraints(), // ✅ Remove default constraints @@ -3201,10 +3212,10 @@ class _ChartScreen1State extends ConsumerState { // color: isActive ? Colors.white : Colors.grey[400], color: isActive ? Color(int.parse((chartScreenData['header_color'] ?? '#898C81') - .replaceFirst('#', '0xff'))) + .replaceFirst('#', '0xff'))) : isDarkTheme - ? Colors.black - : Color(0XFFDFE1DB), + ? Colors.black + : Color(0XFFDFE1DB), borderRadius: BorderRadius.circular(5.0), ), child: Text( @@ -3215,7 +3226,17 @@ class _ChartScreen1State extends ConsumerState { 'NotoKufi', ), // color: isActive ? Colors.black : Colors.white, - color: chartScreenData['main_topic'] == 'SOCIAL' ? isActive ? Colors.white : isDarkTheme ? Colors.white : Colors.black : isActive ? Colors.black : isDarkTheme ? Colors.white : Colors.black, + color: chartScreenData['main_topic'] == 'SOCIAL' + ? isActive + ? Colors.white + : isDarkTheme + ? Colors.white + : Colors.black + : isActive + ? Colors.black + : isDarkTheme + ? Colors.white + : Colors.black, // color: Colors.white, fontWeight: isActive ? FontWeight.w500 : FontWeight.w400, fontSize: 13, @@ -3242,9 +3263,9 @@ class CardWidget extends StatelessWidget { const CardWidget( {Key? key, - required this.card, - required this.chartScreenData, - required this.themeMode}) + required this.card, + required this.chartScreenData, + required this.themeMode}) : super(key: key); @override @@ -3256,7 +3277,7 @@ class CardWidget extends StatelessWidget { final response = card['response'] as List? ?? []; final card_logo = card['card_logo']; double cardHeight = - (chart_type == 'totals' || chart_type == 'averages') ? 180.0 : 130.0; + (chart_type == 'totals' || chart_type == 'averages') ? 180.0 : 130.0; final bodyColor = Color( int.parse( @@ -3314,8 +3335,8 @@ class CardWidget extends StatelessWidget { left: 16.0, right: 16.0, bottom: 2.0, top: 1.0), decoration: BoxDecoration( color: backgroundColor, // Move color inside BoxDecoration - borderRadius: BorderRadius.circular( - 5), // Ensure border radius is applied + borderRadius: + BorderRadius.circular(5), // Ensure border radius is applied ), child: Column( mainAxisSize: MainAxisSize.min, @@ -3373,7 +3394,7 @@ class CardWidget extends StatelessWidget { textAlign: TextAlign.center, maxLines: 2, overflow: - TextOverflow.ellipsis, // Truncate text with '...' + TextOverflow.ellipsis, // Truncate text with '...' style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -3398,7 +3419,7 @@ class CardWidget extends StatelessWidget { fontSize: 11, color: Colors.grey, overflow: - TextOverflow.ellipsis, // Truncate if text overflows + TextOverflow.ellipsis, // Truncate if text overflows ), maxLines: 1, // Limit to one line to prevent overflow textAlign: TextAlign.center, // Ensure proper alignment @@ -3466,11 +3487,11 @@ class CardWidget extends StatelessWidget { decoration: BoxDecoration( color: backgroundColor, // Move color inside BoxDecoration borderRadius: - BorderRadius.circular(5), // Ensure border radius is applied + BorderRadius.circular(5), // Ensure border radius is applied ), child: Column( mainAxisSize: - MainAxisSize.min, // Adjust card height based on content + MainAxisSize.min, // Adjust card height based on content mainAxisAlignment: MainAxisAlignment.center, children: [ // const Icon(Icons.public, @@ -3617,7 +3638,7 @@ class CardWidget extends StatelessWidget { ), textAlign: TextAlign.center, // Ensure proper alignment overflow: - TextOverflow.ellipsis, // Truncate if text overflows + TextOverflow.ellipsis, // Truncate if text overflows ), const SizedBox(width: 1), // Space between text and icon if (response[1]['font_color'] != '') ...[ @@ -3688,4 +3709,4 @@ class CardWidget extends StatelessWidget { // ), // ); } -} \ 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 eb037045..7ee6ea7a 100644 --- a/lib/presentation/Screens/charts/widgets/chart_widget.dart +++ b/lib/presentation/Screens/charts/widgets/chart_widget.dart @@ -10,13 +10,13 @@ import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:d_chart/d_chart.dart'; class ChartWidget extends StatelessWidget { - ChartWidget({ - Key? key, - required this.chartData, - required this.bodyColor, - required this.chartHeader, - required this.isDarkTheme - }) : super(key: key); + ChartWidget( + {Key? key, + required this.chartData, + required this.bodyColor, + required this.chartHeader, + required this.isDarkTheme}) + : super(key: key); final dynamic chartData; final Color bodyColor; final String chartHeader; @@ -102,7 +102,6 @@ class ChartWidget extends StatelessWidget { print('chartHeader $chartHeader'); print(translations[chartHeader]); - String key = translations[chartHeader] ?? chartHeader; print(key); print(colorMap[key]); @@ -280,11 +279,8 @@ class ChartWidget extends StatelessWidget { .withAlpha(alphaFactor); // Use withAlpha() instead of withOpacity() } - List parsePieChartData( - dynamic chartData, - double totalValue, - int? touchedIndex,BuildContext context - ) { + List parsePieChartData(dynamic chartData, + double totalValue, int? touchedIndex, BuildContext context) { debugPrint('Chart Data: ${jsonEncode(chartData)}'); var groupByKeyValue; @@ -301,6 +297,10 @@ class ChartWidget extends StatelessWidget { int index = entry.key; var data = entry.value; + var obsKey = data['ObsKey'] as Map; + int obsKeyLength = obsKey.length; + + print("PIECHART - $index | ObsKey length: $obsKeyLength"); // Handle different types: int, double, and String double value = 0.0; var rawValue = data['ObsValue']['Value']; @@ -319,7 +319,29 @@ class ChartWidget extends StatelessWidget { // double percentage = (value / totalValue) * 100; double percentage = (totalValue > 0) ? (value / totalValue) * 100 : 0.0; bool isTouched = index == touchedIndex; - String displayTitle = title.length > 12 ? '${title.substring(0, 12 )}...' : title; + // String displayTitle = + // title.length > 12 ? '${title.substring(0, 12)}...' : title; + + String displayTitle; + + if (index > 4 || title.length > 20) { + print("DPT1"); + // displayTitle = '${title.substring(0, 12)}...'; + + // int endIndex = title.length < 12 ? title.length : 12; + // displayTitle = '${title.substring(0, endIndex)}...'; + + displayTitle = + title.length > 12 ? '${title.substring(0, 12)}...' : title; + } else { + print("DPT2"); + String part1 = title.substring(0, min(12, title.length)); + String part2 = + title.length > 12 ? title.substring(12, min(24, title.length)) : ''; + + displayTitle = part2.isNotEmpty ? '$part1\n-$part2' : part1; + } + return PieChartSectionData( value: value, // color: Colors.primaries[index % Colors.primaries.length], @@ -327,7 +349,9 @@ class ChartWidget extends StatelessWidget { color: uniqueColors[index % uniqueColors.length], // title: '${percentage.toStringAsFixed(1)}%', // title: percentage >= 0.1 ? '${percentage.toStringAsFixed(1)}%' : '', - title: percentage >= 0.1 ? '$displayTitle\n${percentage.toStringAsFixed(1)}%' : '', + title: percentage >= 0.1 + ? '$displayTitle\n${percentage.toStringAsFixed(1)}%' + : '', radius: isTouched ? 40 : 30, // Increase size when touched @@ -501,10 +525,12 @@ class ChartWidget extends StatelessWidget { color: Colors.blueGrey[800], // Change background color borderRadius: BorderRadius.circular(8), ), - textStyle: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),color: Colors.white), + textStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Colors.white), ), child: Tooltip( message: title, // Full text on hover @@ -513,10 +539,13 @@ class ChartWidget extends StatelessWidget { '$title -- $percentage%', '$title -- %$percentage', ), - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 12,color: isDarkTheme ? Colors.white : null), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 12, + color: isDarkTheme ? Colors.white : null), softWrap: true, maxLines: 2, ), @@ -553,8 +582,8 @@ class ChartWidget extends StatelessWidget { Text( groupLabel, // Displaying groupLabel style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w500, + fontSize: 12, + fontWeight: FontWeight.w500, ), ), ], @@ -705,19 +734,26 @@ class ChartWidget extends StatelessWidget { Text( chartData['chart_heading'] ?? 'Pie Chart', // Chart title from data - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 14, fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black), textAlign: TextAlign.center, ), SizedBox(height: 15), Text( chartData['chart_sub_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 13, fontWeight: FontWeight.w300), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 13, + fontWeight: FontWeight.w300), textAlign: TextAlign.center, ), SizedBox(height: 70), @@ -728,10 +764,7 @@ class ChartWidget extends StatelessWidget { return PieChart( PieChartData( sections: parsePieChartData( - chartData, - totalValue, - touchedIndex.value,context - ), + chartData, totalValue, touchedIndex.value, context), borderData: FlBorderData(show: false), sectionsSpace: 2, centerSpaceRadius: 50, @@ -806,19 +839,26 @@ class ChartWidget extends StatelessWidget { children: [ Text( chartData['chart_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 14, fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black), textAlign: TextAlign.center, ), SizedBox(height: 5), Text( chartData['chart_sub_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 13, fontWeight: FontWeight.w300), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 13, + fontWeight: FontWeight.w300), textAlign: TextAlign.center, ), SizedBox(height: 15), @@ -887,20 +927,22 @@ class ChartWidget extends StatelessWidget { tooltipTextSpans.addAll([ TextSpan( text: ' ● ', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), color: groupColor, fontSize: 14, ), // Circle color ), TextSpan( text: '$groupName - $formattedValue\n', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), color: Colors.white, fontSize: 12, ), @@ -910,10 +952,13 @@ class ChartWidget extends StatelessWidget { return BarTooltipItem( '', - TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),color: Colors.white, fontSize: 12), + TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Colors.white, + fontSize: 12), children: tooltipTextSpans, textAlign: TextAlign.left, ); @@ -928,7 +973,8 @@ class ChartWidget extends StatelessWidget { showTitles: true, reservedSize: 28, getTitlesWidget: (double value, TitleMeta meta) { - return _generateXTitles(chartData,context)[value.toInt()]; + return _generateXTitles( + chartData, context)[value.toInt()]; }, ), ), @@ -985,20 +1031,24 @@ class ChartWidget extends StatelessWidget { // color: Colors.blueGrey[900], borderRadius: BorderRadius.circular(4), ), - textStyle: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),color: Colors.white), + textStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Colors.white), child: Text( group, // group.length > 10 // ? '${group.substring(0, 10)}...' // : group, // overflow: TextOverflow.ellipsis, - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 11), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 11), ), ), ], @@ -1197,19 +1247,26 @@ class ChartWidget extends StatelessWidget { children: [ Text( chartData['chart_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 14, fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black), textAlign: TextAlign.center, ), SizedBox(height: 5), Text( chartData['chart_sub_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 13, fontWeight: FontWeight.w300), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 13, + fontWeight: FontWeight.w300), textAlign: TextAlign.center, ), SizedBox(height: 10), @@ -1229,7 +1286,7 @@ class ChartWidget extends StatelessWidget { lineTouchData: lineTouchData1(context), gridData: gridData(), // titlesData: titlesData1(uniqueXValues), - titlesData: titlesData1(uniqueXValuesProcessed,context), + titlesData: titlesData1(uniqueXValuesProcessed, context), borderData: borderData(), lineBarsData: lineBars, // minY: 10000, @@ -1282,6 +1339,373 @@ class ChartWidget extends StatelessWidget { Map groupColorMap = {}; int colorIndex = 0; + // Extract all years from the chart data + List years = (chartData['response'] as List) + .map( + (entry) => + int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, + ) + .toList(); + + if (years.isEmpty) { + // Return an empty chart if no data + return LineChart( + LineChartData( + titlesData: FlTitlesData(show: false), + lineBarsData: [], + ), + ); + } + + if (years.isNotEmpty) { + // Find the latest available year + int latestYear = years.reduce((a, b) => a > b ? a : b); + selectedYears.add(latestYear); // Include the latest year in selection + } + + // Filter chart data to include only the selected years + List filteredData = + (chartData['response'] as List).where((entry) { + int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0; + return selectedYears.contains(year); + }).toList(); + + Set uniqueXValues = filteredData + .map( + (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']), + ) + .toSet(); + + var chartBarColors = chartData['chart_bar_color'] ?? {}; + Map barColorsMap = {}; + + chartBarColors.forEach((key, value) { + barColorsMap[key] = value.toString(); // Ensure values are strings + }); + bool hasBarColors = barColorsMap.isNotEmpty; + + List keys = chartBarColors['key'] ?? []; + List colors = chartBarColors['color'] ?? []; + + print('RT1keys - $keys'); + print('RT1colors - $colors'); + + // Convert to a map for easy lookup + Map parsedChartBarColors = {}; + for (int i = 0; i < keys.length; i++) { + parsedChartBarColors[keys[i].toString()] = _hexToColor( + colors[i].toString(), + ); + } + print('RTLinr1 - $parsedChartBarColors'); + + for (String group in groupByValues) { + if (parsedChartBarColors.containsKey(group)) { + groupColorMap[group] = + parsedChartBarColors[group]!; // Directly assign as Color + } else { + groupColorMap[group] = + uniqueColors[colorIndex % uniqueColors.length]; + } + colorIndex++; + } + + final Map>> groupedData = {}; + +// Step 1: Group data by PLANT_TYPE + for (var item in filteredData) { + final plantType = item['ObsKey'][groupByKey]; + groupedData.putIfAbsent(plantType, () => []).add(item); + } + +// Step 2: Convert grouped data into List + final List lineBars = []; + final List colorPalette = [ + Color(0xFF6097CD), + Color(0xFFD086A7), + Color(0xFF98BCE5), + Color(0xFFA7B5C5), + Color(0xFFBED3EC), + Color(0xFFD4E3F4), + ]; + + String formatNumber(double value) { + if (value >= 1e12) { + return '${(value / 1e12).toStringAsFixed(2)}T'; + } else if (value >= 1e9) { + return '${(value / 1e9).toStringAsFixed(2)}B'; + } else if (value >= 1e6) { + return '${(value / 1e6).toStringAsFixed(2)}M'; + } else if (value >= 1e3) { + return '${(value / 1e3).toStringAsFixed(2)}K'; + } else { + return value.toStringAsFixed(2); // No decimals for small numbers + } + } + + final getXValue = chartData['chart_type_json']['x'] ?? ''; + groupedData.forEach((plantType, entries) { + final spots = entries.map((entry) { + final year = + double.tryParse(entry['ObsKey'][getXValue].toString()) ?? 0; + final value = + double.tryParse(entry['ObsValue']['Value'].toString()) ?? 0; + return FlSpot(year, value); + }).toList() + ..sort((a, b) => a.x.compareTo(b.x)); // Sort by year + final baseColor = groupColorMap[plantType] ?? Colors.grey; + lineBars.add( + LineChartBarData( + spots: spots, + isCurved: true, + barWidth: 3, + // color: groupColorMap[plantType] ?? Colors.grey, + color: baseColor.withOpacity(0.9), + dotData: FlDotData(show: true), + belowBarData: BarAreaData( + show: true, + gradient: LinearGradient( + colors: [ + // baseColor.withOpacity(0.2), // visible base color + // Colors.white, // fade to white + baseColor.withOpacity(0.4), // increase opacity + baseColor + .withOpacity(0.0), // fade to transparent (not white) + ], + stops: [ + 0.2, // shift teal color start downward (20% from the top) + 1.0, // white at the bottom + ], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + showingIndicators: List.generate(spots.length, (index) => index), + ), + ); + colorIndex++; + }); + + return Scaffold( + backgroundColor: isDarkTheme ? Colors.transparent : Colors.white, + body: Padding( + padding: const EdgeInsets.all(10), + child: LayoutBuilder( + builder: (context, constraints) { + final chartWidth = constraints.maxWidth; + final chartHeight = constraints.maxHeight; + final allSpots = lineBars.expand((line) => line.spots); + final minY = + allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); + final maxY = + allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); + + final xValues = allSpots.map((e) => e.x).toList(); + final minX = xValues.reduce((a, b) => a < b ? a : b).toInt(); + final maxX = xValues.reduce((a, b) => a > b ? a : b).toInt(); + + final paddingFactor = 0.3; // 10% extra padding + + final chartMinY = minY - (maxY - minY) * paddingFactor; + final chartMaxY = maxY + (maxY - minY) * paddingFactor; + + return Column( + crossAxisAlignment: + CrossAxisAlignment.center, // ensures center alignment + children: [ + Padding( + padding: const EdgeInsets.only(top: 0), + child: Text( + chartData['chart_heading'] ?? + 'Production Quantity by Crop Type (Metric Tonne)', + style: TextStyle( + fontFamily: context.translate('Roboto', 'NotoKufi'), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black, + ), + textAlign: TextAlign.center, + ), + ), + // SizedBox(height: 6), + Expanded( + child: Stack( + children: [ + LineChart( + LineChartData( + minY: chartMinY, + maxY: chartMaxY, + lineBarsData: lineBars, + clipData: FlClipData + .all(), // make sure this doesn't clip the left side + + // Add space for tooltip/dot + // extraLeftTitlesReservedWidth: 24, + titlesData: FlTitlesData( + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, meta) { + var style = TextStyle( + color: isDarkTheme + ? Colors.white + : Colors.black, + fontSize: 10, + ); + + // Show only for full years + if (selectedYears + .contains(value.toInt())) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Top tick mark (simulated using a container) + Container( + width: 1, + height: 8, + color: isDarkTheme + ? Colors.white + : Colors.black, + margin: + EdgeInsets.only(bottom: 2), + ), + Text(value.toInt().toString(), + style: style), + ], + ); + } + return const SizedBox.shrink(); + }, + reservedSize: 30, + interval: 1, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: false, + // interval: 5, + reservedSize: 90, + getTitlesWidget: (value, _) => Text( + '${value.toInt()}', + style: TextStyle(fontSize: 12)), + ), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false)), + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false)), + ), + borderData: FlBorderData( + show: true, + border: Border( + left: BorderSide.none, + bottom: BorderSide( + color: isDarkTheme + ? Colors.white + : Colors.black), + ), + ), + gridData: FlGridData(show: false), + lineTouchData: LineTouchData( + enabled: true, + touchTooltipData: LineTouchTooltipData( + // tooltipBgColor: Colors.black.withOpacity(0.7), + fitInsideHorizontally: true, + fitInsideVertically: true, + getTooltipItems: (spots) { + return spots.map((spot) { + final x = spot.x.toInt(); + // if (x == minX || x == maxX) return null; + return LineTooltipItem( + formatNumber(spot.y), + TextStyle( + color: isDarkTheme + ? Colors.white + : Colors.white), + ); + }).toList(); + }, + ), + ), + ), + ), + ...lineBars.expand((barData) { + final List spots = barData.spots; + final color = barData.color ?? Colors.black; + + return spots.map((spot) { + final xPos = ((spot.x - minX) / (maxX - minX)) * + chartWidth; + final yPos = (1 - + (spot.y - chartMinY) / + (chartMaxY - chartMinY)) * + chartHeight; + // Prevent label from going outside on the left + double adjustedLeft = math.max(0, xPos - 30); + return Stack(children: [ + Positioned( + left: + adjustedLeft, // fine-tune horizontal position + top: yPos - 60, // fine-tune vertical position + child: Text( + formatNumber(spot.y), + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 9, + fontWeight: FontWeight.w500, + // color: color, + color: isDarkTheme + ? Colors.white + : Colors.black, + ), + ), + ) + ]); + }); + }).toList(), + ], + ), + ), + SizedBox(height: 12), + Wrap( + // <-- Legend added here + spacing: 12, + runSpacing: 8, + children: groupByValues.map((group) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 12, + height: 12, + color: groupColorMap[group]), + SizedBox(width: 6), + Text( + group, + style: TextStyle( + fontSize: 14, + fontFamily: + context.translate('Roboto', 'NotoKufi'), + ), + ), + ], + ); + }).toList(), + ), + ], + ); + }, + ), + ), + ); + case 'line_trend_2': + final List uniqueColorsLine_trend_2 = [ + Color(0xFF6097CD), + Color(0xFFD086A7), + ]; + Set selectedYears = {1970, 1980, 1990, 2000, 2010, 2020}; + Map groupColorMap = {}; + int colorIndex = 0; // Extract all years from the chart data List years = (chartData['response'] as List) @@ -1328,7 +1752,6 @@ class ChartWidget extends StatelessWidget { }); bool hasBarColors = barColorsMap.isNotEmpty; - List keys = chartBarColors['key'] ?? []; List colors = chartBarColors['color'] ?? []; @@ -1355,358 +1778,6 @@ class ChartWidget extends StatelessWidget { colorIndex++; } - - - - - final Map>> groupedData = {}; - -// Step 1: Group data by PLANT_TYPE - for (var item in filteredData) { - final plantType = item['ObsKey'][groupByKey]; - groupedData.putIfAbsent(plantType, () => []).add(item); - } - -// Step 2: Convert grouped data into List - final List lineBars = []; - final List colorPalette = [ - Color(0xFF6097CD), - Color(0xFFD086A7), - Color(0xFF98BCE5), - Color(0xFFA7B5C5), - Color(0xFFBED3EC), - Color(0xFFD4E3F4), - ]; - - String formatNumber(double value) { - if (value >= 1e12) { - return '${(value / 1e12).toStringAsFixed(2)}T'; - } else if (value >= 1e9) { - return '${(value / 1e9).toStringAsFixed(2)}B'; - } else if (value >= 1e6) { - return '${(value / 1e6).toStringAsFixed(2)}M'; - } else if (value >= 1e3) { - return '${(value / 1e3).toStringAsFixed(2)}K'; - } else { - return value.toStringAsFixed(2); // No decimals for small numbers - } - } - - final getXValue = chartData['chart_type_json']['x'] ?? ''; - groupedData.forEach((plantType, entries) { - final spots = entries.map((entry) { - final year = double.tryParse(entry['ObsKey'][getXValue].toString()) ?? 0; - final value = double.tryParse(entry['ObsValue']['Value'].toString()) ?? 0; - return FlSpot(year, value); - }).toList() - ..sort((a, b) => a.x.compareTo(b.x)); // Sort by year - final baseColor = groupColorMap[plantType] ?? Colors.grey; - lineBars.add( - LineChartBarData( - spots: spots, - isCurved: true, - barWidth: 3, - // color: groupColorMap[plantType] ?? Colors.grey, - color: baseColor.withOpacity(0.9), - dotData: FlDotData(show: true), - belowBarData: BarAreaData( - show: true, - gradient: LinearGradient( - colors: [ - // baseColor.withOpacity(0.2), // visible base color - // Colors.white, // fade to white - baseColor.withOpacity(0.4), // increase opacity - baseColor.withOpacity(0.0), // fade to transparent (not white) - ], - stops: [ - 0.2, // shift teal color start downward (20% from the top) - 1.0, // white at the bottom - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - ), - ), - showingIndicators: List.generate(spots.length, (index) => index), - - ), - ); - colorIndex++; - }); - - return Scaffold( - backgroundColor: isDarkTheme ? Colors.transparent : Colors.white, - body: Padding( - padding: const EdgeInsets.all(10), - child: LayoutBuilder( - builder: (context, constraints) { - final chartWidth = constraints.maxWidth; - final chartHeight = constraints.maxHeight; - final allSpots = lineBars.expand((line) => line.spots); - final minY = allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); - final maxY = allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); - - - final xValues = allSpots.map((e) => e.x).toList(); - final minX = xValues.reduce((a, b) => a < b ? a : b).toInt(); - final maxX = xValues.reduce((a, b) => a > b ? a : b).toInt(); - - final paddingFactor = 0.3; // 10% extra padding - - final chartMinY = minY - (maxY - minY) * paddingFactor; - final chartMaxY = maxY + (maxY - minY) * paddingFactor; - - - return Column( - crossAxisAlignment: CrossAxisAlignment.center, // ensures center alignment - children: [ - Padding( - padding: const EdgeInsets.only(top: 0), - child: Text( - chartData['chart_heading'] ?? 'Production Quantity by Crop Type (Metric Tonne)', - style: TextStyle( - fontFamily: context.translate('Roboto', 'NotoKufi'), - fontSize: 14, - fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black, - ), - textAlign: TextAlign.center, - ), - ), - // SizedBox(height: 6), - Expanded( - child: Stack( - children: [ - LineChart( - LineChartData( - minY: chartMinY, - maxY: chartMaxY, - lineBarsData: lineBars, - clipData: FlClipData.all(), // make sure this doesn't clip the left side - - // Add space for tooltip/dot - // extraLeftTitlesReservedWidth: 24, - titlesData: FlTitlesData( - bottomTitles: AxisTitles( - sideTitles: SideTitles( - showTitles: true, - getTitlesWidget: (value, meta) { - var style = TextStyle( - color: isDarkTheme ? Colors.white : Colors.black, - fontSize: 10, - ); - - // Show only for full years - if (selectedYears.contains(value.toInt())) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - // Top tick mark (simulated using a container) - Container( - width: 1, - height: 8, - color: isDarkTheme ? Colors.white : Colors.black, - margin: EdgeInsets.only(bottom: 2), - ), - Text(value.toInt().toString(), style: style), - ], - ); - } - return const SizedBox.shrink(); - }, - reservedSize: 30, - interval: 1, - ), - ), - leftTitles: AxisTitles( - sideTitles: SideTitles( - showTitles: false, - // interval: 5, - reservedSize: 90, - getTitlesWidget: (value, _) => - Text('${value.toInt()}', style: TextStyle(fontSize: 12)), - ), - ), - topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), - rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), - ), - borderData: FlBorderData( - show: true, - border: Border( - left: BorderSide.none, - bottom: BorderSide(color: isDarkTheme ? Colors.white : Colors.black), - ), - ), - gridData: FlGridData(show: false), - lineTouchData: LineTouchData( - enabled: true, - touchTooltipData: LineTouchTooltipData( - // tooltipBgColor: Colors.black.withOpacity(0.7), - fitInsideHorizontally: true, - fitInsideVertically: true, - getTooltipItems: (spots) { - return spots.map((spot) { - final x = spot.x.toInt(); - // if (x == minX || x == maxX) return null; - return LineTooltipItem( - formatNumber(spot.y), - TextStyle(color: isDarkTheme ? Colors.white : Colors.white), - ); - }).toList(); - }, - ), - ), - ), - ), - - ...lineBars.expand((barData) { - final List spots = barData.spots; - final color = barData.color ?? Colors.black; - - return spots.map((spot) { - final xPos = ((spot.x - minX) / (maxX - minX)) * chartWidth; - final yPos = (1 - (spot.y - chartMinY) / (chartMaxY - chartMinY)) * chartHeight; - // Prevent label from going outside on the left - double adjustedLeft = math.max(0, xPos - 30); - return Stack( - children: [ - Positioned( - left: adjustedLeft, // fine-tune horizontal position - top: yPos - 60, // fine-tune vertical position - child: Text( - formatNumber(spot.y), - textAlign: TextAlign.right, - style: TextStyle( - fontSize: 9, - fontWeight: FontWeight.w500, - // color: color, - color: isDarkTheme ? Colors.white : Colors.black, - ), - ), - ) - ] - ); - - }); - }).toList(), - - ], - ), - ), - SizedBox(height: 12), - Wrap( // <-- Legend added here - spacing: 12, - runSpacing: 8, - children: groupByValues.map((group) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - Container(width: 12, height: 12, color: groupColorMap[group]), - SizedBox(width: 6), - Text( - group, - style: TextStyle( - fontSize: 14, - fontFamily: context.translate('Roboto', 'NotoKufi'), - ), - ), - ], - ); - }).toList(), - ), - ], - ); - - - - }, - ), - ), - ); - case 'line_trend_2': - final List uniqueColorsLine_trend_2 = [ - Color(0xFF6097CD), - Color(0xFFD086A7), - ]; - Set selectedYears = {1970, 1980, 1990, 2000, 2010, 2020}; - Map groupColorMap = {}; - int colorIndex = 0; - - - // Extract all years from the chart data - List years = (chartData['response'] as List) - .map( - (entry) => - int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, - ) - .toList(); - - if (years.isEmpty) { - // Return an empty chart if no data - return LineChart( - LineChartData( - titlesData: FlTitlesData(show: false), - lineBarsData: [], - ), - ); - } - - if (years.isNotEmpty) { - // Find the latest available year - int latestYear = years.reduce((a, b) => a > b ? a : b); - selectedYears.add(latestYear); // Include the latest year in selection - } - - // Filter chart data to include only the selected years - List filteredData = - (chartData['response'] as List).where((entry) { - int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0; - return selectedYears.contains(year); - }).toList(); - - Set uniqueXValues = filteredData - .map( - (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']), - ) - .toSet(); - - var chartBarColors = chartData['chart_bar_color'] ?? {}; - Map barColorsMap = {}; - - chartBarColors.forEach((key, value) { - barColorsMap[key] = value.toString(); // Ensure values are strings - }); - bool hasBarColors = barColorsMap.isNotEmpty; - - - List keys = chartBarColors['key'] ?? []; - List colors = chartBarColors['color'] ?? []; - - print('RT1keys - $keys'); - print('RT1colors - $colors'); - - // Convert to a map for easy lookup - Map parsedChartBarColors = {}; - for (int i = 0; i < keys.length; i++) { - parsedChartBarColors[keys[i].toString()] = _hexToColor( - colors[i].toString(), - ); - } - print('RTLinr1 - $parsedChartBarColors'); - - for (String group in groupByValues) { - if (parsedChartBarColors.containsKey(group)) { - groupColorMap[group] = - parsedChartBarColors[group]!; // Directly assign as Color - } else { - groupColorMap[group] = - uniqueColors[colorIndex % uniqueColors.length]; - } - colorIndex++; - } - - - - - final Map>> groupedData = {}; // Step 1: Group data by PLANT_TYPE @@ -1746,7 +1817,8 @@ class ChartWidget extends StatelessWidget { Map> yearGenderMap = {}; for (var entry in filteredData) { - int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'].toString()) ?? 0; + int year = + int.tryParse(entry['ObsKey']['TIME_PERIOD'].toString()) ?? 0; String gender = entry['ObsKey']['GENDER']; double value = @@ -1788,7 +1860,8 @@ class ChartWidget extends StatelessWidget { // baseColor.withOpacity(0.2), // visible base color // Colors.white, // fade to white baseColor.withOpacity(0.4), // increase opacity - baseColor.withOpacity(0.0), // fade to transparent (not white) + baseColor + .withOpacity(0.0), // fade to transparent (not white) ], stops: [ 0.2, // shift teal color start downward (20% from the top) @@ -1799,7 +1872,6 @@ class ChartWidget extends StatelessWidget { ), ), showingIndicators: List.generate(spots.length, (index) => index), - ), ); colorIndex++; @@ -1814,9 +1886,10 @@ class ChartWidget extends StatelessWidget { final chartWidth = constraints.maxWidth; final chartHeight = constraints.maxHeight; final allSpots = lineBars.expand((line) => line.spots); - final minY = allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); - final maxY = allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); - + final minY = + allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); + final maxY = + allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); final xValues = allSpots.map((e) => e.x).toList(); final minX = xValues.reduce((a, b) => a < b ? a : b).toInt(); @@ -1827,18 +1900,20 @@ class ChartWidget extends StatelessWidget { final chartMinY = minY - (maxY - minY) * paddingFactor; final chartMaxY = maxY + (maxY - minY) * paddingFactor; - return Column( - crossAxisAlignment: CrossAxisAlignment.center, // ensures center alignment + crossAxisAlignment: + CrossAxisAlignment.center, // ensures center alignment children: [ Padding( padding: const EdgeInsets.only(top: 0), child: Text( - chartData['chart_heading'] ?? 'Production Quantity by Crop Type (Metric Tonne)', + chartData['chart_heading'] ?? + 'Production Quantity by Crop Type (Metric Tonne)', style: TextStyle( fontFamily: context.translate('Roboto', 'NotoKufi'), fontSize: 14, - fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black, ), textAlign: TextAlign.center, ), @@ -1852,7 +1927,8 @@ class ChartWidget extends StatelessWidget { minY: chartMinY, maxY: chartMaxY, lineBarsData: lineBars, - clipData: FlClipData.all(), // make sure this doesn't clip the left side + clipData: FlClipData + .all(), // make sure this doesn't clip the left side // Add space for tooltip/dot // extraLeftTitlesReservedWidth: 24, @@ -1862,12 +1938,15 @@ class ChartWidget extends StatelessWidget { showTitles: true, getTitlesWidget: (value, meta) { var style = TextStyle( - color: isDarkTheme ? Colors.white : Colors.black, + color: isDarkTheme + ? Colors.white + : Colors.black, fontSize: 10, ); // Show only for full years - if (selectedYears.contains(value.toInt())) { + if (selectedYears + .contains(value.toInt())) { return Column( mainAxisSize: MainAxisSize.min, children: [ @@ -1875,10 +1954,14 @@ class ChartWidget extends StatelessWidget { Container( width: 1, height: 8, - color: isDarkTheme ? Colors.white : Colors.black, - margin: EdgeInsets.only(bottom: 2), + color: isDarkTheme + ? Colors.white + : Colors.black, + margin: + EdgeInsets.only(bottom: 2), ), - Text(value.toInt().toString(), style: style), + Text(value.toInt().toString(), + style: style), ], ); } @@ -1893,18 +1976,24 @@ class ChartWidget extends StatelessWidget { showTitles: false, // interval: 5, reservedSize: 90, - getTitlesWidget: (value, _) => - Text('${value.toInt()}', style: TextStyle(fontSize: 12)), + getTitlesWidget: (value, _) => Text( + '${value.toInt()}', + style: TextStyle(fontSize: 12)), ), ), - topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), - rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false)), + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false)), ), borderData: FlBorderData( show: true, border: Border( left: BorderSide.none, - bottom: BorderSide(color: isDarkTheme ? Colors.white : Colors.black), + bottom: BorderSide( + color: isDarkTheme + ? Colors.white + : Colors.black), ), ), gridData: FlGridData(show: false), @@ -1920,18 +2009,24 @@ class ChartWidget extends StatelessWidget { // if (x == minX || x == maxX) return null; // Use barIndex to determine which line this belongs to final barIndex = spot.barIndex; - if (lineBars[barIndex].spots.isEmpty) return null; + if (lineBars[barIndex].spots.isEmpty) + return null; // Check the group name (plantType) from your groupedData order - final plantType = groupedData.keys.toList()[barIndex]; + final plantType = + groupedData.keys.toList()[barIndex]; print('plantType $plantType'); - if (plantType != "Male" && plantType != "ذكر") { + if (plantType != "Male" && + plantType != "ذكر") { return null; } return LineTooltipItem( formatNumber(spot.y), - TextStyle(color: isDarkTheme ? Colors.white : Colors.white), + TextStyle( + color: isDarkTheme + ? Colors.white + : Colors.white), ); }).toList(); }, @@ -1939,38 +2034,40 @@ class ChartWidget extends StatelessWidget { ), ), ), - ...lineBars.expand((barData) { final List spots = barData.spots; final color = barData.color ?? Colors.black; return spots.map((spot) { - final xPos = ((spot.x - minX) / (maxX - minX)) * chartWidth; - final yPos = (1 - (spot.y - chartMinY) / (chartMaxY - chartMinY)) * chartHeight; + final xPos = ((spot.x - minX) / (maxX - minX)) * + chartWidth; + final yPos = (1 - + (spot.y - chartMinY) / + (chartMaxY - chartMinY)) * + chartHeight; // Prevent label from going outside on the left double adjustedLeft = math.max(0, xPos - 30); - return Stack( - children: [ - Positioned( - left: adjustedLeft, // fine-tune horizontal position - top: yPos - 70, // fine-tune vertical position - child: Text( - formatNumber(spot.y), - textAlign: TextAlign.right, - style: TextStyle( - fontSize: 9, - fontWeight: FontWeight.w500, - // color: color, - color: isDarkTheme ? Colors.white : Colors.black, - ), - ), - ) - ] - ); - + return Stack(children: [ + Positioned( + left: + adjustedLeft, // fine-tune horizontal position + top: yPos - 70, // fine-tune vertical position + child: Text( + formatNumber(spot.y), + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 9, + fontWeight: FontWeight.w500, + // color: color, + color: isDarkTheme + ? Colors.white + : Colors.black, + ), + ), + ) + ]); }); }).toList(), - ], ), ), @@ -1997,9 +2094,6 @@ class ChartWidget extends StatelessWidget { // ), ], ); - - - }, ), ), @@ -2104,19 +2198,26 @@ class ChartWidget extends StatelessWidget { children: [ Text( chartData['chart_heading'] ?? '', // Chart title from data - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 14, fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black), textAlign: TextAlign.center, ), SizedBox(height: 5), Text( chartData['chart_sub_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 13, fontWeight: FontWeight.w300), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 13, + fontWeight: FontWeight.w300), textAlign: TextAlign.center, ), SizedBox(height: 10), @@ -2198,30 +2299,34 @@ class ChartWidget extends StatelessWidget { // ? yAxisLabels[groupIndex] // : ''; // if (rod.toY == 0) return null; - final originalValue = rod.toY == 0.1 ? 0.0 : rod.toY; + final originalValue = + rod.toY == 0.1 ? 0.0 : rod.toY; String displayValue; if (originalValue == 0.0) { displayValue = '0'; // 🔥 clean and simple } else { displayValue = (chartConversion != null && - chartConversion.isNotEmpty && - number_format != null && - chartConversion.isNotEmpty) + chartConversion.isNotEmpty && + number_format != null && + chartConversion.isNotEmpty) ? formatNumberConversion( - originalValue, - chartConversion, - number_format, - ) + originalValue, + chartConversion, + number_format, + ) : formatNumber(originalValue); } return BarTooltipItem( displayValue, - TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: isDarkTheme ? Colors.white : Colors.black, + TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme + ? Colors.white + : Colors.black, fontSize: 12, fontWeight: FontWeight.w400, ), @@ -2245,11 +2350,12 @@ class ChartWidget extends StatelessWidget { right: 8.0, ), child: Text( - '${value.toInt()}', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + '${value.toInt()}', + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), ), ); }, @@ -2263,8 +2369,12 @@ class ChartWidget extends StatelessWidget { getTitlesWidget: (value, meta) { if (value.toInt() < xAxisData.length) { String title = xAxisData[value.toInt()]; + // String displayTitle = title.length > 10 + // ? title.substring(0, 10) + '...' + // : title; + String displayTitle = title.length > 10 - ? title.substring(0, 10) + '...' + ? '${title.substring(0, 7)}\n${title.substring(7, 12)}..' : title; print('barChartVALUECHECKTITLE $title'); print( @@ -2281,22 +2391,26 @@ class ChartWidget extends StatelessWidget { child: Transform.rotate( // angle: -0.5, angle: 0, + // angle: + // title.length > 10 ? -0.5 : 0, - child: TooltipTheme( + child: TooltipTheme( data: TooltipThemeData( decoration: BoxDecoration( color: Colors .black, // Change background color // color: Colors.blueGrey[800], // Change background color borderRadius: - BorderRadius.circular( + BorderRadius.circular( 8, ), // Optional: rounded corners ), - textStyle: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + textStyle: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), color: Colors.white, ), // Change text color ), @@ -2306,15 +2420,18 @@ class ChartWidget extends StatelessWidget { // title, displayTitle, softWrap: true, + maxLines: 2, textAlign: TextAlign.center, - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), fontSize: 10, ), - overflow: - TextOverflow.ellipsis, + // overflow: + // TextOverflow.ellipsis, ), ), ), @@ -2348,8 +2465,10 @@ class ChartWidget extends StatelessWidget { ), barGroups: List.generate( xAxisData.length, - (index) { - final value = double.tryParse(yAxisData[index].toString()) ?? 0; + (index) { + final value = double.tryParse( + yAxisData[index].toString()) ?? + 0; print('GGGGGG $value'); return BarChartGroupData( x: index, @@ -2459,10 +2578,14 @@ class ChartWidget extends StatelessWidget { children: [ Text( chartData['chart_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 14, fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black), textAlign: TextAlign.center, ), // SizedBox(height: 5), @@ -2532,8 +2655,9 @@ class ChartWidget extends StatelessWidget { return Padding( padding: const EdgeInsets.only(right: 8.0), child: Text( - '${value.toInt()}', - style: TextStyle(fontFamily: context.translate( + '${value.toInt()}', + style: TextStyle( + fontFamily: context.translate( 'Roboto', 'NotoKufi', )), @@ -2561,10 +2685,12 @@ class ChartWidget extends StatelessWidget { child: Text( xAxisData[value.toInt()], textAlign: TextAlign.right, - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 10), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 10), softWrap: true, maxLines: 2, ), @@ -2711,19 +2837,26 @@ class ChartWidget extends StatelessWidget { children: [ Text( chartData['chart_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 14, fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black), textAlign: TextAlign.center, ), SizedBox(height: 5), Text( '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 13, fontWeight: FontWeight.w300), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 13, + fontWeight: FontWeight.w300), textAlign: TextAlign.center, ), SizedBox(height: 10), @@ -2796,10 +2929,11 @@ class ChartWidget extends StatelessWidget { 8, ), // Optional: rounded corners ), - textStyle: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + textStyle: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), color: Colors.white, ), // Change text color ), @@ -2810,10 +2944,12 @@ class ChartWidget extends StatelessWidget { softWrap: true, maxLines: 2, textAlign: TextAlign.right, - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 10), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 10), // overflow: TextOverflow.ellipsis, ), ), @@ -2901,10 +3037,11 @@ class ChartWidget extends StatelessWidget { return BarTooltipItem( '$groupLabel\n$crop', - TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), color: Colors.white, fontWeight: FontWeight.bold, ), @@ -2912,10 +3049,11 @@ class ChartWidget extends StatelessWidget { TextSpan( text: '- ${(chartConversion != null && chartConversion.isNotEmpty && number_format != null) ? formatNumberConversion(rod.toY, chartConversion, number_format) : formatNumber(rod.toY)}', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), color: Colors.white, fontWeight: FontWeight.w500, ), @@ -3027,19 +3165,26 @@ class ChartWidget extends StatelessWidget { children: [ Text( chartData['chart_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 14, fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 14, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black), textAlign: TextAlign.center, ), SizedBox(height: 5), Text( chartData['chart_sub_heading'] ?? '', - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 13, fontWeight: FontWeight.w300), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 13, + fontWeight: FontWeight.w300), textAlign: TextAlign.center, ), SizedBox(height: 5), @@ -3206,11 +3351,14 @@ class ChartWidget extends StatelessWidget { return BarTooltipItem( '0', // Display "0" instead of hiding textAlign: TextAlign.right, - TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: isDarkTheme ? Colors.white : Colors.black, + TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: isDarkTheme + ? Colors.white + : Colors.black, fontSize: 12, ), ); @@ -3238,11 +3386,13 @@ class ChartWidget extends StatelessWidget { return BarTooltipItem( formattedValue, textAlign: TextAlign.right, - TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: isDarkTheme ? Colors.white : Colors.black, + TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: + isDarkTheme ? Colors.white : Colors.black, fontSize: 12, ), ); @@ -3262,10 +3412,12 @@ class ChartWidget extends StatelessWidget { child: Text( value.toInt().toString(), textAlign: TextAlign.center, - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 12), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 12), ), ); }, @@ -3303,10 +3455,12 @@ class ChartWidget extends StatelessWidget { 0) ? TextAlign.right : TextAlign.center, - style: TextStyle(fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),fontSize: 12), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 12), softWrap: true, maxLines: 2, ), @@ -3375,7 +3529,8 @@ class ChartWidget extends StatelessWidget { // ), // ) const SizedBox(height: 10), // Space between chart and legend - _buildChartLegend(groupedCrops, parsedChartBarColors, uniqueColors,context), + _buildChartLegend( + groupedCrops, parsedChartBarColors, uniqueColors, context), ], ); case 'demo_line': @@ -3399,9 +3554,9 @@ class ChartWidget extends StatelessWidget { // Now map to Color Map parsedChartBarColors = chartBarColrs.map(( - key, - value, - ) { + key, + value, + ) { return MapEntry(key, _hexToColor(value)); }); @@ -3413,20 +3568,20 @@ class ChartWidget extends StatelessWidget { parsedChartBarColors.containsKey(group)) { groupColorMap[group] = parsedChartBarColors[group]!; } else { - groupColorMap[group] = uniqueColors[colorIndex % uniqueColors.length]; + groupColorMap[group] = + uniqueColors[colorIndex % uniqueColors.length]; colorIndex++; } } - print('Group-Color Map: $groupColorMap'); // Extract all years from the chart data List years = (chartData['response'] as List) .map( - (entry) => - int.tryParse(entry['ObsKey'][groupByKey] ?? '0') ?? 0, - ).toList(); + (entry) => int.tryParse(entry['ObsKey'][groupByKey] ?? '0') ?? 0, + ) + .toList(); years.sort(); print(years); print('years $years'); @@ -3449,7 +3604,7 @@ class ChartWidget extends StatelessWidget { // Filter chart data to only include entries within the last 5 years List filteredData = - (chartData['response'] as List).where((entry) { + (chartData['response'] as List).where((entry) { int year = int.tryParse(entry['ObsKey'][groupByKey] ?? '0') ?? 0; return year >= minYear && year <= maxYear; }).toList(); @@ -3474,7 +3629,6 @@ class ChartWidget extends StatelessWidget { Color(0xFFD4E3F4), ]; - String formatNumber(double value) { if (value >= 1e12) { return '${(value / 1e12).toStringAsFixed(2)}T'; @@ -3489,11 +3643,13 @@ class ChartWidget extends StatelessWidget { } } - final getXValue = chartData['chart_type_json']['x'] ?? ''; + final getXValue = chartData['chart_type_json']['x'] ?? ''; groupedData.forEach((plantType, entries) { final spots = entries.map((entry) { - final year = double.tryParse(entry['ObsKey'][getXValue].toString()) ?? 0; - final value = double.tryParse(entry['ObsValue']['Value'].toString()) ?? 0; + final year = + double.tryParse(entry['ObsKey'][getXValue].toString()) ?? 0; + final value = + double.tryParse(entry['ObsValue']['Value'].toString()) ?? 0; return FlSpot(year, value); }).toList() ..sort((a, b) => a.x.compareTo(b.x)); // Sort by year @@ -3513,7 +3669,8 @@ class ChartWidget extends StatelessWidget { // baseColor.withOpacity(0.2), // visible base color // Colors.white, // fade to white baseColor.withOpacity(0.4), // increase opacity - baseColor.withOpacity(0.0), // fade to transparent (not white) + baseColor + .withOpacity(0.0), // fade to transparent (not white) ], stops: [ 0.2, // shift teal color start downward (20% from the top) @@ -3524,7 +3681,6 @@ class ChartWidget extends StatelessWidget { ), ), showingIndicators: List.generate(spots.length, (index) => index), - ), ); colorIndex++; @@ -3539,9 +3695,10 @@ class ChartWidget extends StatelessWidget { final chartWidth = constraints.maxWidth; final chartHeight = constraints.maxHeight; final allSpots = lineBars.expand((line) => line.spots); - final minY = allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); - final maxY = allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); - + final minY = + allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); + final maxY = + allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); final xValues = allSpots.map((e) => e.x).toList(); final minX = xValues.reduce((a, b) => a < b ? a : b).toInt(); @@ -3552,18 +3709,20 @@ class ChartWidget extends StatelessWidget { final chartMinY = minY - (maxY - minY) * paddingFactor; final chartMaxY = maxY + (maxY - minY) * paddingFactor; - return Column( - crossAxisAlignment: CrossAxisAlignment.center, // ensures center alignment + crossAxisAlignment: + CrossAxisAlignment.center, // ensures center alignment children: [ Padding( padding: const EdgeInsets.only(top: 0), child: Text( - chartData['chart_heading'] ?? 'Production Quantity by Crop Type (Metric Tonne)', + chartData['chart_heading'] ?? + 'Production Quantity by Crop Type (Metric Tonne)', style: TextStyle( fontFamily: context.translate('Roboto', 'NotoKufi'), fontSize: 14, - fontWeight: FontWeight.w400,color: isDarkTheme ? Colors.white : Colors.black, + fontWeight: FontWeight.w400, + color: isDarkTheme ? Colors.white : Colors.black, ), textAlign: TextAlign.center, ), @@ -3577,7 +3736,8 @@ class ChartWidget extends StatelessWidget { minY: chartMinY, maxY: chartMaxY, lineBarsData: lineBars, - clipData: FlClipData.all(), // make sure this doesn't clip the left side + clipData: FlClipData + .all(), // make sure this doesn't clip the left side // Add space for tooltip/dot // extraLeftTitlesReservedWidth: 24, @@ -3587,12 +3747,15 @@ class ChartWidget extends StatelessWidget { showTitles: true, getTitlesWidget: (value, meta) { var style = TextStyle( - color: isDarkTheme ? Colors.white : Colors.black, + color: isDarkTheme + ? Colors.white + : Colors.black, fontSize: 10, ); // Show only for full years - if (value.toInt() >= 2013 && value.toInt() <= 2022) { + if (value.toInt() >= 2013 && + value.toInt() <= 2022) { return Column( mainAxisSize: MainAxisSize.min, children: [ @@ -3600,10 +3763,14 @@ class ChartWidget extends StatelessWidget { Container( width: 1, height: 8, - color: isDarkTheme ? Colors.white : Colors.black, - margin: EdgeInsets.only(bottom: 2), + color: isDarkTheme + ? Colors.white + : Colors.black, + margin: + EdgeInsets.only(bottom: 2), ), - Text(value.toInt().toString(), style: style), + Text(value.toInt().toString(), + style: style), ], ); } @@ -3618,18 +3785,24 @@ class ChartWidget extends StatelessWidget { showTitles: false, // interval: 5, reservedSize: 90, - getTitlesWidget: (value, _) => - Text('${value.toInt()}', style: TextStyle(fontSize: 12)), + getTitlesWidget: (value, _) => Text( + '${value.toInt()}', + style: TextStyle(fontSize: 12)), ), ), - topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), - rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false)), + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false)), ), borderData: FlBorderData( show: true, border: Border( left: BorderSide.none, - bottom: BorderSide(color: isDarkTheme ? Colors.white : Colors.black), + bottom: BorderSide( + color: isDarkTheme + ? Colors.white + : Colors.black), ), ), gridData: FlGridData(show: false), @@ -3645,7 +3818,10 @@ class ChartWidget extends StatelessWidget { // if (x == minX || x == maxX) return null; return LineTooltipItem( formatNumber(spot.y), - TextStyle(color: isDarkTheme ? Colors.white : Colors.white), + TextStyle( + color: isDarkTheme + ? Colors.white + : Colors.white), ); }).toList(); }, @@ -3705,50 +3881,58 @@ class ChartWidget extends StatelessWidget { final color = barData.color ?? Colors.black; return spots.map((spot) { - final xPos = ((spot.x - minX) / (maxX - minX)) * chartWidth; - final yPos = (1 - (spot.y - chartMinY) / (chartMaxY - chartMinY)) * chartHeight; + final xPos = ((spot.x - minX) / (maxX - minX)) * + chartWidth; + final yPos = (1 - + (spot.y - chartMinY) / + (chartMaxY - chartMinY)) * + chartHeight; // Prevent label from going outside on the left double adjustedLeft = math.max(0, xPos - 30); - return Stack( - children: [ - Positioned( - left: adjustedLeft, // fine-tune horizontal position - top: yPos - 60, // fine-tune vertical position - child: Text( - formatNumber(spot.y), - textAlign: TextAlign.right, - style: TextStyle( - fontSize: 9, - fontWeight: FontWeight.w500, - // color: color, - color: isDarkTheme ? Colors.white : Colors.black, - ), - ), - ) - ] - ); - + return Stack(children: [ + Positioned( + left: + adjustedLeft, // fine-tune horizontal position + top: yPos - 60, // fine-tune vertical position + child: Text( + formatNumber(spot.y), + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 9, + fontWeight: FontWeight.w500, + // color: color, + color: isDarkTheme + ? Colors.white + : Colors.black, + ), + ), + ) + ]); }); }).toList(), - ], ), ), SizedBox(height: 12), - Wrap( // <-- Legend added here + Wrap( + // <-- Legend added here spacing: 12, runSpacing: 8, children: groupByValues.map((group) { return Row( mainAxisSize: MainAxisSize.min, children: [ - Container(width: 12, height: 12, color: groupColorMap[group]), + Container( + width: 12, + height: 12, + color: groupColorMap[group]), SizedBox(width: 6), Text( group, style: TextStyle( fontSize: 14, - fontFamily: context.translate('Roboto', 'NotoKufi'), + fontFamily: + context.translate('Roboto', 'NotoKufi'), ), ), ], @@ -3757,16 +3941,12 @@ class ChartWidget extends StatelessWidget { ), ], ); - - - }, ), ), ); - - // case 'd_chart_grouped_bar_horizantal': + // case 'd_chart_grouped_bar_horizantal': // return DChartBar( // vertical: false, // <--- Important: rotate the chart // barGroupingType: BarGroupingType.grouped, @@ -3825,10 +4005,7 @@ class ChartWidget extends StatelessWidget { // String formattedValue = (value / 1000000).toStringAsFixed(1) + 'M'; return Text( value.toStringAsFixed(1), - style: TextStyle( - color: Colors.black, - fontSize: 12 - ), + style: TextStyle(color: Colors.black, fontSize: 12), ); }, ), @@ -4098,8 +4275,7 @@ class ChartWidget extends StatelessWidget { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), ], textAlign: TextAlign.left, @@ -4194,7 +4370,7 @@ class ChartWidget extends StatelessWidget { ); } - FlTitlesData titlesData1(Set xValues,BuildContext context) { + FlTitlesData titlesData1(Set xValues, BuildContext context) { print('tileDATa1xvalueline2 - $xValues'); double findClosest(double value, Set values) { @@ -4297,8 +4473,7 @@ class ChartWidget extends StatelessWidget { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ); } @@ -4335,8 +4510,7 @@ class ChartWidget extends StatelessWidget { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ), + )), ), ), ), @@ -4500,7 +4674,7 @@ class ChartWidget extends StatelessWidget { } // Function to dynamically generate titles for the x-axis (time periods) - List _generateXTitles(dynamic chartData,BuildContext context) { + List _generateXTitles(dynamic chartData, BuildContext context) { Set timePeriods = {}; for (var entry in chartData['response']) { timePeriods.add(entry['ObsKey']['TIME_PERIOD']); @@ -4512,9 +4686,7 @@ class ChartWidget extends StatelessWidget { fontFamily: context.translate( 'Roboto', 'NotoKufi', - ) - ) - ); + ))); }).toList(); } @@ -4545,7 +4717,7 @@ class ChartWidget extends StatelessWidget { print('formattedValue - $formattedValue'); return Text(formattedValue, style: TextStyle( - fontSize: 10, + fontSize: 10, )); } return const SizedBox.shrink(); @@ -4836,10 +5008,10 @@ class ChartWidget extends StatelessWidget { } Widget _buildChartLegend( - Map> groupedCrops, - Map parsedChartBarColors, - List uniqueColors,BuildContext context -) { + Map> groupedCrops, + Map parsedChartBarColors, + List uniqueColors, + BuildContext context) { // Extract unique crop types Set uniqueCropTypes = groupedCrops.values.expand((list) => list).toSet(); @@ -4866,13 +5038,13 @@ Widget _buildChartLegend( children: [ CircleAvatar(radius: 6, backgroundColor: cropColor), const SizedBox(width: 4), - Text(cropType, style: TextStyle( - fontSize: 12, - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ) - )), + Text(cropType, + style: TextStyle( + fontSize: 12, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ))), ], ); }).toList(), diff --git a/lib/presentation/components/dialogs.dart b/lib/presentation/components/dialogs.dart index 328c0d48..cc9d3ad4 100644 --- a/lib/presentation/components/dialogs.dart +++ b/lib/presentation/components/dialogs.dart @@ -40,12 +40,12 @@ extension Dialogs on BuildContext { /// If [errorDialogBuilder] is provided, an /// [showLogBtn] is also true exception is thrown; Future loaderWithErrorDialog( - FutureOr Function() computation, { - Future Function( - Object error, [ - StackTrace stackTrace, - ])? errorDialogBuilder, - }) async { + FutureOr Function() computation, { + Future Function( + Object error, [ + StackTrace stackTrace, + ])? errorDialogBuilder, + }) async { final loaderContext = await _pushLoaderDialog(); late final T value; try { @@ -104,14 +104,14 @@ extension Dialogs on BuildContext { color: Color(0xFF898C81), fontWeight: FontWeight.w700)), content: content.length > 300 ? SingleChildScrollView( - child: Text(content, - style: TextStyle(color: Color(0xFF898C81))), - ) + child: Text(content, + style: TextStyle(color: Color(0xFF898C81))), + ) : Text( - content, - style: TextStyle( - color: Color(0xFF898C81)), // Set content text color - ), + content, + style: TextStyle( + color: Color(0xFF898C81)), // Set content text color + ), actions: [ TextButton( onPressed: Navigator.of( @@ -123,11 +123,11 @@ extension Dialogs on BuildContext { backgroundColor: Color(0xFFB68A34), // Background color foregroundColor: Colors.white, // Font (text) color side: BorderSide( - // color: Color(0xFF92722A)), // Border outline color + // color: Color(0xFF92722A)), // Border outline color color: Color(0xFFB68A34)), // Border outline color shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(8), // Optional: Rounded corners + BorderRadius.circular(8), // Optional: Rounded corners ), padding: EdgeInsets.symmetric( horizontal: 16, vertical: 12), // Optional: Padding @@ -152,11 +152,11 @@ extension Dialogs on BuildContext { ); Future confirmationDialog( - String titleText, - String contentText, { - String cancelText = 'Cancel', - String confirmText = 'Confirm', - }) => + String titleText, + String contentText, { + String cancelText = 'Cancel', + String confirmText = 'Confirm', + }) => showDialog( context: this, barrierDismissible: false, @@ -183,4 +183,4 @@ extension Dialogs on BuildContext { ], ), ); -} \ No newline at end of file +} diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index d8e78a6b..a87e8c4f 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -37,7 +37,7 @@ import 'package:http/http.dart' as http; import 'package:url_launcher/url_launcher.dart'; import '../../Screens/auth_verification/registration.dart'; import 'package:pocketbase/pocketbase.dart'; - import 'package:uae_stat/config/api_config.dart'; +import 'package:uae_stat/config/api_config.dart'; import '../../components/indicators/locale_provider.dart'; import '../../components/my_toggle.dart'; @@ -213,8 +213,7 @@ class LoginRoute extends HookConsumerWidget { final response = await http.get(url); final body = json.decode(response.body); if (response.statusCode == 200) { - return body['status'] ?? 'Reset link sent successfully.'; - + return body['status'] ?? 'Reset link sent successfully.'; } else { final errorResponse = json.decode(response.body); throw Exception( @@ -275,10 +274,10 @@ class LoginRoute extends HookConsumerWidget { title: const Text('Enable App Links'), content: const Text( 'To enable links like www.fcsc.com to open in this app:\n\n' - '1. Tap "Open Settings".\n' - '2. Then tap on "Supported web addresses".\n' - '3. Make sure your domain is enabled.\n\n' - 'This helps open web links directly in the app.', + '1. Tap "Open Settings".\n' + '2. Then tap on "Supported web addresses".\n' + '3. Make sure your domain is enabled.\n\n' + 'This helps open web links directly in the app.', ), actions: [ TextButton( @@ -302,7 +301,8 @@ class LoginRoute extends HookConsumerWidget { } void openAppLinkSettings() { - const packageName = 'ae.gov.fcsc.frontend'; // Replace with your app's package + const packageName = + 'ae.gov.fcsc.frontend'; // Replace with your app's package final intent = AndroidIntent( action: 'android.settings.APP_OPEN_BY_DEFAULT_SETTINGS', data: 'package:$packageName', @@ -320,21 +320,25 @@ class LoginRoute extends HookConsumerWidget { } } - Future initializeTheme(BuildContext context,WidgetRef ref, String userId) async { + Future initializeTheme( + BuildContext context, WidgetRef ref, String userId) async { final themeService = ThemeBaseService(); final theme = await themeService.getUserTheme(userId); // e.g., "dark" final platformBrightness = MediaQuery.of(context).platformBrightness; - ref.read(themeProvider.notifier).updateTheme(AppThemeExtension.fromString(theme),platformBrightness); + ref + .read(themeProvider.notifier) + .updateTheme(AppThemeExtension.fromString(theme), platformBrightness); final themeMode = ref.watch(themeProvider); print('themeMode Login'); print('themeMode $themeMode'); } - Future oAuthGoogleAndAppleLogin(BuildContext context, WidgetRef ref,platform) async { + Future oAuthGoogleAndAppleLogin( + BuildContext context, WidgetRef ref, platform) async { print(platform); try { final authData = - await pb.collection('users').authWithOAuth2(platform, (url) async { + await pb.collection('users').authWithOAuth2(platform, (url) async { await launchUrl(url); }); print(authData); @@ -363,15 +367,15 @@ class LoginRoute extends HookConsumerWidget { await initializeTheme(context, ref, userId); final session = await context.loaderWithErrorDialog( - () => ref + () => ref .read( - authUseCaseProvider.notifier, - ) + authUseCaseProvider.notifier, + ) .googleAndAppleAuthencation(authData), errorDialogBuilder: ( - error, [ - StackTrace? stackTrace, - ]) { + error, [ + StackTrace? stackTrace, + ]) { if (error == LoginError.invalidEmailPw) { return context.simpleDialog( title: context.translate( @@ -395,7 +399,7 @@ class LoginRoute extends HookConsumerWidget { // Extract intendedPath from query parameters (if coming from redirect) final String? intendedPath = - GoRouterState.of(context).uri.queryParameters['intendedPath']; + GoRouterState.of(context).uri.queryParameters['intendedPath']; print("Extracted intendedPath after login: $intendedPath"); if (isProfileComplete) { @@ -427,8 +431,8 @@ class LoginRoute extends HookConsumerWidget { Future loginCountApi(String userId) async { if (userId.isNotEmpty) { final url = - // Uri.parse("https://pb.venbait.in/api/login_success?id=$userId"); - Uri.parse('$apiUrl/api/login_success?id=$userId'); + // Uri.parse("https://pb.venbait.in/api/login_success?id=$userId"); + Uri.parse('$apiUrl/api/login_success?id=$userId'); try { final response = await http.get(url); @@ -567,7 +571,6 @@ class LoginRoute extends HookConsumerWidget { // } // } - @override Widget build(BuildContext context, WidgetRef ref) { ref.listen>(connectivityProvider, (previous, hasInternet) { @@ -703,7 +706,7 @@ class LoginRoute extends HookConsumerWidget { color: Color(0xFF92722A)), // Border outline color shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(8), // Optional: Rounded corners + BorderRadius.circular(8), // Optional: Rounded corners ), padding: EdgeInsets.symmetric( horizontal: 10, vertical: 10), // Optional: Padding @@ -792,7 +795,6 @@ class LoginRoute extends HookConsumerWidget { ), ); } - }, style: TextButton.styleFrom( padding: EdgeInsets.zero, @@ -917,7 +919,7 @@ class LoginRoute extends HookConsumerWidget { await saveUserId(userId, loginCount); await getDeviceToken(context, userId); - await initializeTheme(context,ref,userId); + await initializeTheme(context, ref, userId); } try { final bool isProfileComplete = await profileStatus(userId, ref); @@ -995,7 +997,7 @@ class LoginRoute extends HookConsumerWidget { ), backgroundColor: WidgetStatePropertyAll( // isDarkTheme ? Color(0xFFB68A34) : Color(0xFFB68A34), - Color(0xFFB68A34), + Color(0xFFB68A34), // MyTheme.topicColor(IndicatorTopic.social), ), // surfaceTintColor: MaterialStatePropertyAll( @@ -1024,9 +1026,11 @@ class LoginRoute extends HookConsumerWidget { ), ), 6.horizontalSpace, - Icon( + Icon( Icons.chevron_right_outlined, - color: isDarkTheme ? Colors.white : Colors.white, // Set your desired color here + color: isDarkTheme + ? Colors.white + : Colors.white, // Set your desired color here ) ], ), @@ -1156,7 +1160,7 @@ class LoginRoute extends HookConsumerWidget { ), style: TextStyle( fontSize: locale?.languageCode == 'ar' ? 12 : 14, - color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), + color: isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFF898C81), ), ), const TextSpan( @@ -1235,7 +1239,7 @@ class LoginRoute extends HookConsumerWidget { width: double.infinity, child: OutlinedButton( onPressed: () async { - oAuthGoogleAndAppleLogin(context,ref,'google'); + oAuthGoogleAndAppleLogin(context, ref, 'google'); }, style: OutlinedButton.styleFrom( side: const BorderSide(color: Color(0xFF000000)), @@ -1255,7 +1259,8 @@ class LoginRoute extends HookConsumerWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( - MiscIconAssetPath.signInWithGoogle, // replace with your Google icon asset + MiscIconAssetPath + .signInWithGoogle, // replace with your Google icon asset height: 20, ), const SizedBox(width: 10), @@ -1275,7 +1280,7 @@ class LoginRoute extends HookConsumerWidget { width: double.infinity, child: OutlinedButton( onPressed: () async { - oAuthGoogleAndAppleLogin(context,ref,'apple'); + oAuthGoogleAndAppleLogin(context, ref, 'apple'); }, style: OutlinedButton.styleFrom( side: const BorderSide(color: Color(0xFF000000)), @@ -1295,7 +1300,8 @@ class LoginRoute extends HookConsumerWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( - MiscIconAssetPath.signInWithApple, // replace with your Google icon asset + MiscIconAssetPath + .signInWithApple, // replace with your Google icon asset height: 20, ), const SizedBox(width: 10), @@ -1333,7 +1339,8 @@ class LoginRoute extends HookConsumerWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( - MiscIconAssetPath.signInWithUAEPass, // replace with your Google icon asset + MiscIconAssetPath + .signInWithUAEPass, // replace with your Google icon asset height: 20, ), const SizedBox(width: 10), @@ -1497,7 +1504,6 @@ class LoginRoute extends HookConsumerWidget { // } } - // abstract class _LocalAuthRepo { // static const _key = 'session'; // static const _storage = FlutterSecureStorage(); @@ -1522,4 +1528,4 @@ class LoginRoute extends HookConsumerWidget { // ); // // static Future clear() => _storage.delete(key: _key); -// } \ No newline at end of file +// } diff --git a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart index af49f255..2b5ed274 100644 --- a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart +++ b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart @@ -201,7 +201,7 @@ class _MyHomePageState extends ConsumerState { context.go('/login'); // Redirect to login after logout } - void _showExitConfirmation(BuildContext context,isDarkTheme) { + void _showExitConfirmation(BuildContext context, isDarkTheme) { double myheight = MediaQuery.of(context).size.height; showDialog( context: context, @@ -215,10 +215,15 @@ class _MyHomePageState extends ConsumerState { title: Text( context.translate('Log Out Confirmation', 'تأكيد تسجيل الخروج'), textAlign: TextAlign.center, - style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: isDarkTheme ? Colors.white : Colors.black, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: isDarkTheme ? Colors.white : Colors.black, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), ), content: Padding( padding: const EdgeInsets.all(20.0), @@ -285,10 +290,14 @@ class _MyHomePageState extends ConsumerState { .scaleDown, // Prevents wrapping while adjusting text size child: Text( context.translate('Log Out', 'تسجيل الخروج'), - style: TextStyle(color: Colors.white, fontSize: 16, fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ),), + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + ), textAlign: TextAlign.center, ), ), @@ -355,14 +364,18 @@ class _MyHomePageState extends ConsumerState { canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - _showExitConfirmation(context,isDarkTheme); // Show exit confirmation dialog + _showExitConfirmation( + context, isDarkTheme); // Show exit confirmation dialog }, child: BaseScaffold( title: Center( child: SizedBox( height: myheight / 5, width: mywidth / 3, - child: Image(image: AssetImage(isDarkTheme ? LogoAssetPath.uaeStatDark : LogoAssetPath.uaeStatLight)))), + child: Image( + image: AssetImage(isDarkTheme + ? LogoAssetPath.uaeStatDark + : LogoAssetPath.uaeStatLight)))), body: EconomyStatsWidget(), ), ); @@ -1107,7 +1120,6 @@ class EconomyStatsState extends ConsumerState { fetchData(locale?.languageCode ?? 'en', themeMode); - // _fetchUserData(); _loadLoginCount(); } @@ -1166,11 +1178,12 @@ class EconomyStatsState extends ConsumerState { // } // } - Future fetchData(locale,themeMode) async { + Future fetchData(locale, themeMode) async { // const baseUrl = 'https://pb.venbait.in/api/getHomePageData'; const baseUrl = '$apiUrl/api/getHomePageData'; try { - final response = await http.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); + final response = await http + .get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); if (response.statusCode == 200) { setState(() { data = json.decode(response.body); @@ -1229,7 +1242,7 @@ class EconomyStatsState extends ConsumerState { MediaQuery.of(context).platformBrightness == Brightness.dark); final themeString = isDark ? 'dark' : 'light'; - fetchData(localeCode,themeString); + fetchData(localeCode, themeString); }); final isConnected = ref.watch(connectivityProvider); @@ -1257,7 +1270,7 @@ class EconomyStatsState extends ConsumerState { MediaQuery.of(context).platformBrightness == Brightness.dark); final themeString = isDark ? 'dark' : 'light'; - fetchData(localeCode,themeString); + fetchData(localeCode, themeString); }); final isDarkTheme = ref.watch(themeProvider) == ThemeMode.dark || @@ -1269,7 +1282,9 @@ class EconomyStatsState extends ConsumerState { if (isLoading) { return Container( - color: Color(0x98FFFCE5), // Semi-transparent background + color: isDarkTheme + ? Colors.black + : Colors.white, // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -1406,7 +1421,6 @@ class EconomyStatsState extends ConsumerState { borderColor, mainTopic['color_pattern'], mainTopic['main_topic']), - ), ), ], @@ -1492,10 +1506,10 @@ List _buildRows(List> tileData, Color borderColor, .map((tile) { return Expanded( child: Container( - margin: EdgeInsets.only( - right: 5, - left: 5, - ), + margin: EdgeInsets.only( + right: 5, + left: 5, + ), child: InfoCard( // title: tile['data_set_tile_heading']!, title: tile['data_set_tile_heading'] ?? 'Unknown Title', @@ -1510,8 +1524,7 @@ List _buildRows(List> tileData, Color borderColor, mainTopic: mainTopic, onTap: () {}, ), - ) - ); + )); }).toList(), ), ), @@ -1538,13 +1551,15 @@ class RoundedCornerContainer extends StatelessWidget { return Container( decoration: BoxDecoration( color: backgroundColor, - borderRadius: BorderRadius.only(topRight: Radius.circular(20),topLeft: Radius.circular(20)), // Rounded corners + borderRadius: BorderRadius.only( + topRight: Radius.circular(20), + topLeft: Radius.circular(20)), // Rounded corners ), child: Center( child: Text( text, style: textStyle ?? - TextStyle( + TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', @@ -1595,8 +1610,7 @@ class InfoCard extends StatelessWidget { final encodedTitle = Uri.encodeComponent(title); final encodedKey = Uri.encodeQueryComponent('home'); - return Consumer( - builder: (context, ref, _) { + return Consumer(builder: (context, ref, _) { final themeMode = ref.watch(themeProvider); final isDarkTheme = themeMode == ThemeMode.dark || (themeMode == ThemeMode.system && @@ -1614,7 +1628,8 @@ class InfoCard extends StatelessWidget { margin: const EdgeInsets.symmetric(horizontal: 0), // padding: const EdgeInsets.all(10), - padding: const EdgeInsets.only(bottom: 0.5, top: 1, left: 10, right: 10), + padding: + const EdgeInsets.only(bottom: 0.5, top: 1, left: 10, right: 10), decoration: BoxDecoration( color: isDarkTheme ? Color(0xFF111111) : null, border: Border.all(color: bordercolor), @@ -1722,9 +1737,6 @@ class InfoCard extends StatelessWidget { ), ), ); - } - ); - - + }); } } 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 49f3b0d7..2a232ff3 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart @@ -61,8 +61,8 @@ class _ManageUserRouterState extends ConsumerState { await _pb.admins .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); final result = await _pb.collection('users').getFullList( - filter: 'role="user"', - ); + filter: 'role="user"', + ); setState(() { userData = result.map((record) { @@ -108,10 +108,10 @@ class _ManageUserRouterState extends ConsumerState { } void _sort( - Comparable? Function(User user) getField, - int columnIndex, - bool ascending, - ) { + Comparable? Function(User user) getField, + int columnIndex, + bool ascending, + ) { setState(() { _sortColumnIndex = columnIndex; _isAscending = ascending; @@ -160,9 +160,9 @@ class _ManageUserRouterState extends ConsumerState { AppLocalizations.of(context)!.status_success, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), ), ); @@ -174,14 +174,14 @@ class _ManageUserRouterState extends ConsumerState { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - context.translate( - 'Error updating status: $e', '$e خطأ في تحديث الحالة: '), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), - )), + context.translate( + 'Error updating status: $e', '$e خطأ في تحديث الحالة: '), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + )), ); } } @@ -201,7 +201,7 @@ class _ManageUserRouterState extends ConsumerState { borderRadius: BorderRadius.circular(5.0), // Rounded corners ), contentPadding: - EdgeInsets.zero, // Ensure no padding issues with close icon + EdgeInsets.zero, // Ensure no padding issues with close icon content: Stack( children: [ Padding( @@ -232,7 +232,7 @@ class _ManageUserRouterState extends ConsumerState { 'NotoKufi', ), fontWeight: - FontWeight.bold, // Makes newStatus bold + FontWeight.bold, // Makes newStatus bold fontSize: 18, color: Color(0xFF898C81), ), @@ -301,11 +301,11 @@ class _ManageUserRouterState extends ConsumerState { }, style: TextButton.styleFrom( backgroundColor: - Color(0xFFAA8E83), // Set background color + Color(0xFFAA8E83), // Set background color foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(10.0), // Set text color + BorderRadius.circular(10.0), // Set text color ), ), child: Text( @@ -406,314 +406,320 @@ class _ManageUserRouterState extends ConsumerState { AppLocalizations.of(context)!.manage_user, style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), body: isLoading ? Container( - color: Color(0x98FFFCE5), // Semi-transparent background - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - margin: EdgeInsets.symmetric( - horizontal: 40), // Left & Right space - child: LinearProgressIndicator( - minHeight: 5, // Adjust thickness - backgroundColor: - Colors.grey[100], // Optional: Background color - valueColor: AlwaysStoppedAnimation( - Color(0xFFAA8E83)), // Loader color - ), - ), - ], - ), - ) - : SingleChildScrollView( - child: Padding( - padding: - const EdgeInsets.only(left: 10.0, right: 10.0, top: 3.0), - child: Column( - children: [ - - Container( - height: 40, - decoration: BoxDecoration( - color: isDarkTheme ? Color(0xFF000000) : Colors.white, - borderRadius: BorderRadius.circular(5.0), - border: Border.all(width: 2, color: Color(0xFFA0A0A0)), - ), - child: Padding( - padding: EdgeInsets.only(left: 5.0), - child: TextField( - decoration: InputDecoration( - hintText: AppLocalizations.of(context)!.search, - hintStyle: TextStyle( - color: isDarkTheme ? Color(0xFF898C81) : Color(0xFF898C81), - fontFamily: context.translate('Roboto', 'NotoKufi'), - fontSize: 18, - // height: 1.8, - ), - prefixIconConstraints: BoxConstraints( - maxWidth: 42, - maxHeight: 42, - ), - prefixIcon: Container( - padding: EdgeInsets.only(right: 5, left: 5), - alignment: Alignment.center, - child: SvgPicture.asset( - MiscIconAssetPath.Search, - semanticsLabel: 'Search', - colorFilter: ColorFilter.mode(Color(0xFFAA8E83), BlendMode.srcIn), - height: 18, - width: 18, - ), - ), - // contentPadding: EdgeInsets.symmetric(vertical: 12, horizontal: 18.0), - border: InputBorder.none, + color: isDarkTheme + ? Colors.black + : Colors.white, // Semi-transparent background + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.symmetric( + horizontal: 40), // Left & Right space + child: LinearProgressIndicator( + minHeight: 5, // Adjust thickness + backgroundColor: + Colors.grey[100], // Optional: Background color + valueColor: AlwaysStoppedAnimation( + Color(0xFFAA8E83)), // Loader color ), - onChanged: filterUsers, ), - ), + ], ), - SizedBox(height: myheight / 40), - filteredUserData.isEmpty - ? Center( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(height: myheight / 5), - - // Icon(Icons.search, - // size: 60, color: Colors.grey), - Image.asset( - MiscIconAssetPath.group, - width: 60, - height: 60, + ) + : SingleChildScrollView( + child: Padding( + padding: + const EdgeInsets.only(left: 10.0, right: 10.0, top: 3.0), + child: Column( + children: [ + Container( + height: 40, + decoration: BoxDecoration( + color: isDarkTheme ? Color(0xFF000000) : Colors.white, + borderRadius: BorderRadius.circular(5.0), + border: + Border.all(width: 2, color: Color(0xFFA0A0A0)), ), - - SizedBox(height: 15), - // Space between icon and text - Text( - AppLocalizations.of(context)! - .no_result_found, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.grey[700], - ), - ), - - SizedBox(height: 12), // Space between texts - FittedBox( - child: Text( - context.translate( - "We couldn't find anything matching your search.", - 'لم نعثر على أي شيء يطابق بحثك.'), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), + child: Padding( + padding: EdgeInsets.only(left: 5.0), + child: TextField( + decoration: InputDecoration( + hintText: AppLocalizations.of(context)!.search, + hintStyle: TextStyle( + color: isDarkTheme + ? Color(0xFF898C81) + : Color(0xFF898C81), + fontFamily: + context.translate('Roboto', 'NotoKufi'), fontSize: 18, - color: Color(0xFF898C81)), - textAlign: TextAlign.center, - ), - ), - ], - ), - ), - ) - : SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: ConstrainedBox( - constraints: BoxConstraints( - minWidth: MediaQuery.of(context).size.width, - ), - child: DataTable( - sortColumnIndex: _sortColumnIndex, - sortAscending: _isAscending, - columns: [ - DataColumn( - label: Text( - AppLocalizations.of(context)!.user_name, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), - ), - onSort: (columnIndex, ascending) { - _sort( - (user) => - user.userName.toLowerCase(), - columnIndex, - ascending); - }, - ), - DataColumn( - label: Text( - AppLocalizations.of(context)!.email_id, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), - ), - onSort: (columnIndex, ascending) { - _sort( - (user) => - user.emailId.toLowerCase(), - columnIndex, - ascending); - }, - ), - DataColumn( - label: Text( - AppLocalizations.of(context)!.reg_date, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), - ), - onSort: (columnIndex, ascending) { - _sort( - (user) => DateFormat('dd/MM/yyyy') - .parse(user.registrationDate), - columnIndex, - ascending, - ); - }, - ), - DataColumn( - label: Text( - AppLocalizations.of(context)!.status, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), - ), - onSort: (columnIndex, ascending) { - _sort( - (user) => user.status.toLowerCase(), - columnIndex, - ascending); - }, - ), - ], - rows: filteredUserData.isEmpty - ? [ - DataRow( - cells: List.generate( - 4, // Ensure it matches the number of DataColumns - (index) => DataCell( - index == 0 - ? Text( - AppLocalizations.of( - context)! - .no_result_found, - style: TextStyle( - fontFamily: context - .translate( - 'Roboto', - 'NotoKufi', - ), - fontStyle: FontStyle - .italic), - ) - : const Text( - ''), // Empty cells for other columns - placeholder: true, - ), - ), - ), - ] - : filteredUserData.map((user) { - return DataRow( - cells: [ - DataCell( - Text( - user.userName, - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - )), + // height: 1.8, ), + prefixIconConstraints: BoxConstraints( + maxWidth: 42, + maxHeight: 42, + ), + prefixIcon: Container( + padding: EdgeInsets.only(right: 5, left: 5), + alignment: Alignment.center, + child: SvgPicture.asset( + MiscIconAssetPath.Search, + semanticsLabel: 'Search', + colorFilter: ColorFilter.mode( + Color(0xFFAA8E83), BlendMode.srcIn), + height: 18, + width: 18, + ), + ), + // contentPadding: EdgeInsets.symmetric(vertical: 12, horizontal: 18.0), + border: InputBorder.none, ), - DataCell(Text( - user.emailId, - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - )), - )), - DataCell(Text( - user.registrationDate, - style: TextStyle( - fontFamily: - context.translate( - 'Roboto', - 'NotoKufi', - )), - )), - DataCell( - DropdownButton( - value: user.status, - items: statusOptions.entries - .map((status) { - return DropdownMenuItem< - String>( - value: status.key, - child: Text( - status.value, + onChanged: filterUsers, + ), + ), + ), + SizedBox(height: myheight / 40), + filteredUserData.isEmpty + ? Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: myheight / 5), + + // Icon(Icons.search, + // size: 60, color: Colors.grey), + Image.asset( + MiscIconAssetPath.group, + width: 60, + height: 60, + ), + + SizedBox(height: 15), + // Space between icon and text + Text( + AppLocalizations.of(context)! + .no_result_found, style: TextStyle( - fontFamily: - context.translate( + fontFamily: context.translate( 'Roboto', 'NotoKufi', ), - color: getStatusColor( - status.key), + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.grey[700], ), ), - ); - }).toList(), - onChanged: (newStatus) { - print(user); - if (newStatus != null) { - _showConfirmationDialog( - user, - newStatus, - statusOptions[ - newStatus]!, - ); - } - }, + + SizedBox(height: 12), // Space between texts + FittedBox( + child: Text( + context.translate( + "We couldn't find anything matching your search.", + 'لم نعثر على أي شيء يطابق بحثك.'), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 18, + color: Color(0xFF898C81)), + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ) + : SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: ConstrainedBox( + constraints: BoxConstraints( + minWidth: MediaQuery.of(context).size.width, + ), + child: DataTable( + sortColumnIndex: _sortColumnIndex, + sortAscending: _isAscending, + columns: [ + DataColumn( + label: Text( + AppLocalizations.of(context)!.user_name, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + onSort: (columnIndex, ascending) { + _sort( + (user) => + user.userName.toLowerCase(), + columnIndex, + ascending); + }, + ), + DataColumn( + label: Text( + AppLocalizations.of(context)!.email_id, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + onSort: (columnIndex, ascending) { + _sort( + (user) => + user.emailId.toLowerCase(), + columnIndex, + ascending); + }, + ), + DataColumn( + label: Text( + AppLocalizations.of(context)!.reg_date, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + onSort: (columnIndex, ascending) { + _sort( + (user) => DateFormat('dd/MM/yyyy') + .parse(user.registrationDate), + columnIndex, + ascending, + ); + }, + ), + DataColumn( + label: Text( + AppLocalizations.of(context)!.status, + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + onSort: (columnIndex, ascending) { + _sort( + (user) => user.status.toLowerCase(), + columnIndex, + ascending); + }, + ), + ], + rows: filteredUserData.isEmpty + ? [ + DataRow( + cells: List.generate( + 4, // Ensure it matches the number of DataColumns + (index) => DataCell( + index == 0 + ? Text( + AppLocalizations.of( + context)! + .no_result_found, + style: TextStyle( + fontFamily: context + .translate( + 'Roboto', + 'NotoKufi', + ), + fontStyle: FontStyle + .italic), + ) + : const Text( + ''), // Empty cells for other columns + placeholder: true, + ), + ), + ), + ] + : filteredUserData.map((user) { + return DataRow( + cells: [ + DataCell( + Text( + user.userName, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + ), + ), + DataCell(Text( + user.emailId, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + )), + DataCell(Text( + user.registrationDate, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + )), + )), + DataCell( + DropdownButton( + value: user.status, + items: statusOptions.entries + .map((status) { + return DropdownMenuItem< + String>( + value: status.key, + child: Text( + status.value, + style: TextStyle( + fontFamily: + context.translate( + 'Roboto', + 'NotoKufi', + ), + color: getStatusColor( + status.key), + ), + ), + ); + }).toList(), + onChanged: (newStatus) { + print(user); + if (newStatus != null) { + _showConfirmationDialog( + user, + newStatus, + statusOptions[ + newStatus]!, + ); + } + }, + ), + ), + ], + ); + }).toList(), + ), ), ), - ], - ); - }).toList(), - ), + ], ), ), - ], - ), - ), - ), + ), ), ); } @@ -734,4 +740,4 @@ class User { required this.registrationDate, this.status = 'Pending', }); -} \ No newline at end of file +} diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart index 5e4969e6..02976b85 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/notification/notification_details.dart @@ -239,8 +239,8 @@ class _NotificationDetailsState extends ConsumerState { body: isLoading ? Container( color: isDarkTheme - ? Color(0xFF111111) - : Color(0x98FFFCE5), // Semi-transparent background + ? Colors.black + : Colors.white, // Semi-transparent background child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -309,9 +309,8 @@ class _NotificationDetailsState extends ConsumerState { style: TextStyle( fontSize: 12, fontWeight: FontWeight.w400, - color: isDarkTheme - ? Colors.white - : Color(0xFF8E8E8E), + color: + isDarkTheme ? Colors.white : Color(0xFF8E8E8E), fontFamily: context.translate( 'Roboto', 'NotoKufi', diff --git a/lib/presentation/routes/drawer_routes/profile/profile_route.dart b/lib/presentation/routes/drawer_routes/profile/profile_route.dart index 00a07f44..80683d7a 100644 --- a/lib/presentation/routes/drawer_routes/profile/profile_route.dart +++ b/lib/presentation/routes/drawer_routes/profile/profile_route.dart @@ -270,7 +270,7 @@ class ProfileRoute extends HookConsumerWidget { ), ), Expanded( - child: bodyContent, + child: Container(color: Colors.lightGreenAccent, child: bodyContent), ), ], );