diff --git a/.run/main.dart.run.xml b/.run/main.dart.run.xml index 4a58a7c9..4767aff8 100644 --- a/.run/main.dart.run.xml +++ b/.run/main.dart.run.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/assets/app_tour/right_down.png b/assets/app_tour/right_down.png new file mode 100644 index 00000000..324c148c Binary files /dev/null and b/assets/app_tour/right_down.png differ diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index 1678f6e3..dc0af316 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -316,6 +316,7 @@ import '../presentation/Screens/demo_home.dart'; import '../presentation/Screens/profilepage.dart'; import '../presentation/routes/auth_routes/login_route.dart'; import '../presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/bookmark.dart'; import '../presentation/routes/drawer_routes/Drawer Items/edit_profile.dart'; import '../presentation/routes/drawer_routes/Drawer Items/feedback.dart'; import '../presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart'; @@ -470,6 +471,10 @@ final GoRouter router = GoRouter( path: '/editProfile', builder: (context, state) => EditProfile(), ), + GoRoute( + path: '/bookmark', + builder: (context, state) => BookMark(), + ), GoRoute( path: '/manageuser', builder: (context, state) => ManageUserRouter(), diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index dac0f961..a37e9e39 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -90,6 +90,6 @@ "economy": "Access detailed statistics and drill-down pages for KPIs in the Economy category to uncover key trends and metrics.", "bookMark": "Bookmark important KPIs or datasets for quick and easy access anytime through the Bookmarks section.", "toggle": "Switch between English and Arabic using the language toggle at the top-right corner for a bilingual experience.", - "tour_navBar": "Use the navigation bar to quickly access Profile, Feedback, User Guide, Notifications, and other key app features.", - "mainMenu": "Access dedicated pages and additional features by selecting options from the Main Menu." + "tour_navBar": "Access dedicated pages and additional features by selecting options from the Main Menu.", + "mainMenu": "Use the navigation bar to quickly access Profile, Feedback, User Guide, Notifications, and other key app features." } diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index 291e7e1d..566b834f 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -2,11 +2,14 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/presentation/Screens/charts/services/api_service.dart'; import 'package:uae_stat/presentation/Screens/charts/widgets/chart_widget.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart'; import '../filters/search_filter_helper.dart'; class ChartScreen1 extends ConsumerStatefulWidget { @@ -50,6 +53,12 @@ class _ChartScreen1State extends ConsumerState { int _activeTabIndex = 0; dynamic _tabsData = []; + late List marriageTargets; + late List previousMarriageTargets; + late TutorialCoachMark tutorialCoachMark; + final GlobalKey chartKey = GlobalKey(); + final GlobalKey bookMarkKey = GlobalKey(); + final GlobalKey cardKey= GlobalKey(); @override void initState() { @@ -64,6 +73,586 @@ class _ChartScreen1State extends ConsumerState { onTabSelected(_tabsData[0]['id']); } }); + + WidgetsBinding.instance.addPostFrameCallback((_) { + _startTutorialAfterRender(); + }); + } + + void handleSkip() { + tutorialCoachMark.skip(); + debugPrint('Skip clicked'); + ref.read(chartsTourProvider.notifier).state = true; + ref.read(previousChartsTourProvider.notifier).state = true; + ref.read(homeTourProvider.notifier).state = true; + ref.read( previousHomeTourProvider.notifier).state = true; + ref.read(scaffoldTourProvider.notifier).state = true; + ref.read(previousScaffoldTourProvider.notifier).state = true; + context.go('/myhomepage'); + } + + void _kpiTutorialCoachMark() { + debugPrint('Not Initialized and Started'); + // _calculateMarkPosition(); + _initmarriageTargets(); + debugPrint('Initialized and Started'); + tutorialCoachMark = TutorialCoachMark( + paddingFocus: 0, + useSafeArea: true, + + pulseEnable: false, + hideSkip: true, + targets: marriageTargets, + onFinish: () { + context.go('/myhomepage'); + debugPrint('Marriage Tutorial Finished'); + }, + + )..show(context: context); + } + + + void _startTutorialAfterRender() { + final chartTour = ref.watch(chartsTourProvider); + final previousChartTour = ref.watch(previousChartsTourProvider); + debugPrint('render problem'); + if (cardKey.currentContext != null && !chartTour) { + _kpiTutorialCoachMark(); + } else if(cardKey.currentContext != null && !previousChartTour) { + _previousKpiTutorial(); + } + else if (!chartTour || !previousChartTour){ + Future.delayed(Duration(milliseconds: 100), _startTutorialAfterRender); + }else{ + return; + } + + } + + void _previousKpiTutorial() { + _initpreviousTargets(); + tutorialCoachMark = TutorialCoachMark( + paddingFocus: 0, + useSafeArea: true, + pulseEnable: false, + hideSkip: true, + targets: previousMarriageTargets, + onFinish: () { + context.go('/myhomepage'); + debugPrint('Previous Marriage Tutorial Finished'); + }, + + )..show(context: context); + + } + void _initmarriageTargets(){ + final double screenWidth= MediaQuery.of(context).size.width; + final double screenHeight= MediaQuery.of(context).size.height; + marriageTargets=[ + TargetFocus( + identify: 'cardKey', + keyTarget: cardKey, + shape: ShapeLightFocus.RRect, + paddingFocus: 0, + contents: [ + createTargetContent( + text: AppLocalizations.of(context)!.kpiCards, + alignment: ContentAlign.top, + gap:55, + space: 0, + ), + TargetContent( + align: ContentAlign.bottom, + child: SizedBox( + width: double.infinity, + height: MediaQuery.of(context).size.height*0.3, + child: Stack( + children: [ + Positioned( + bottom: 35, + left: 16, + right: 16, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ElevatedButton( + onPressed: () => handleSkip(), + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + side: const BorderSide(color: Colors.white), + backgroundColor: Colors.transparent, + elevation: 0, + ), + child: const Text( + 'Skip', + style: TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + ), + Column( + children: [ + Text( + '3/7', + style: const TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + const SizedBox(height: 3), + Row( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.white, width: 2.0), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () { + ref.read(chartsTourProvider.notifier).state=true; + ref.read(previousHomeTourProvider.notifier).state=false; + tutorialCoachMark.finish(); + }, + ), + ), + const SizedBox(width: 10), + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF7DAFBC), + border: Border.all(color:Color(0xFF7DAFBC), width: 1.5), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_forward, color: Colors.white), + onPressed: () { + tutorialCoachMark.next(); + }, + ), + ), + ], + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + TargetContent( + padding: EdgeInsets.only(bottom: 0,top : 0,), + align: ContentAlign.top, + child: SizedBox( + width: MediaQuery.of(context).size.width, + height:MediaQuery.of(context).size.height*0.69 , + child: Stack( + children: [ + Positioned( + left: MediaQuery.of(context).size.width*0.40, + bottom: 0, + child: Image.asset( + 'assets/app_tour/leftUp.png', + width: 100, + height: 90, + ), + ), + ] + ), + + ), + ), + ], + ), + TargetFocus( + identify: 'BookMarkKey', + keyTarget: bookMarkKey, + shape: ShapeLightFocus.RRect, + paddingFocus: 1, + contents: [ + createTargetContent( + text: AppLocalizations.of(context)!.bookMark, + alignment: ContentAlign.bottom, + gap: 53, + space: 50, + ), + TargetContent( + align: ContentAlign.bottom, + child: SizedBox( + width: double.infinity, + height: MediaQuery.of(context).size.height*0.60, + child: Stack( + children: [ + Positioned( + bottom: 35, + left: 16, + right: 16, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ElevatedButton( + onPressed: () => handleSkip(), + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + side: const BorderSide(color: Colors.white), + backgroundColor: Colors.transparent, + elevation: 0, + ), + child: const Text( + 'Skip', + style: TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + ), + Column( + children: [ + Text( + '4/7', + style: const TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + const SizedBox(height: 3), + Row( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.white, width: 2.0), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () { + tutorialCoachMark.previous(); + }, + ), + ), + const SizedBox(width: 10), + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF7DAFBC), + border: Border.all(color: Color(0xFF7DAFBC), width: 1), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_forward, color: Colors.white), + onPressed: () { + ref.read(chartsTourProvider.notifier).state=true; + ref.read(scaffoldTourProvider.notifier).state=false; + tutorialCoachMark.finish(); + }, + ), + ), + ], + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + TargetContent( + padding: EdgeInsets.only(left:0, top:0), + align: ContentAlign.right, + child: Container( + width: screenWidth/4, + height: screenHeight, + child: Stack( + children: [ + Image.asset( + 'assets/app_tour/leftDown.png', + fit: BoxFit.contain, + ), + // Positioned( + // top: 0, + // left: MediaQuery.of(context).size.width* 0.5, + // child: SizedBox( + // width: 50, + // height: 100, + // child: Image.asset( + // 'assets/app_tour/bookmark2.png', + // fit: BoxFit.contain, + // ), + // ), + // ), + ], + ), + ), + ), + ], + ), + + ]; + } + void _initpreviousTargets(){ + final double screenWidth= MediaQuery.of(context).size.width; + final double screenHeight= MediaQuery.of(context).size.height; + previousMarriageTargets=[ + TargetFocus( + identify: 'BookMarkKey', + keyTarget: bookMarkKey, + shape: ShapeLightFocus.RRect, + contents: [ + createTargetContent( + text: AppLocalizations.of(context)!.bookMark, + space: 50, + alignment: ContentAlign.bottom, + gap: 23, + ), + TargetContent( + align: ContentAlign.bottom, + child: SizedBox( + width: double.infinity, + height: MediaQuery.of(context).size.height*0.60, + child: Stack( + children: [ + Positioned( + bottom: 35, + left: 16, + right: 16, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ElevatedButton( + onPressed: () => handleSkip(), + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + side: const BorderSide(color: Colors.white), + backgroundColor: Colors.transparent, + elevation: 0, + ), + child: const Text( + 'Skip', + style: TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + ), + Column( + children: [ + Text( + '4/7', + style: const TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + const SizedBox(height: 3), + Row( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.white, width: 2.0), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () { + tutorialCoachMark.next(); + }, + ), + ), + const SizedBox(width: 10), + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF7DAFBC), + border: Border.all(color:Color(0xFF7DAFBC), width: 1.5), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_forward, color: Colors.white), + onPressed: () { + ref.read(chartsTourProvider.notifier).state=true; + ref.read(scaffoldTourProvider.notifier).state=false; + tutorialCoachMark.finish(); + }, + ), + ), + ], + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + TargetContent( + padding: EdgeInsets.only(left:0, top: 10), + align: ContentAlign.right, + child: Container( + width: screenWidth/4, + height: screenHeight, + child: Stack( + children: [ + Image.asset( + 'assets/app_tour/leftDown.png', + fit: BoxFit.contain, + ), + // Positioned( + // top: 0, + // left: MediaQuery.of(context).size.width* 0.5, + // child: SizedBox( + // width: 50, + // height: 100, + // child: Image.asset( + // 'assets/app_tour/bookmark2.png', + // fit: BoxFit.contain, + // ), + // ), + // ), + ], + ), + ), + ), + ], + ), + TargetFocus( + identify: 'cardKey', + keyTarget: cardKey, + shape: ShapeLightFocus.RRect, + contents: [ + createTargetContent( + text: AppLocalizations.of(context)!.kpiCards, + space: 0, + alignment: ContentAlign.top, + gap:50, + ), + TargetContent( + align: ContentAlign.bottom, + child: SizedBox( + width: double.infinity, + height: MediaQuery.of(context).size.height*0.30, + child: Stack( + children: [ + Positioned( + bottom: 35, + left: 16, + right: 16, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ElevatedButton( + onPressed: () => handleSkip(), + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + side: const BorderSide(color: Colors.white), + backgroundColor: Colors.transparent, + elevation: 0, + ), + child: const Text( + 'Skip', + style: TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + ), + Column( + children: [ + Text( + '3/7', + style: const TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + const SizedBox(height: 3), + Row( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.white, width: 2.0), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_back, color: Colors.white), + onPressed: () { + ref.read(previousChartsTourProvider.notifier).state=true; + ref.read(previousHomeTourProvider.notifier).state=false; + tutorialCoachMark.finish(); + }, + ), + ), + const SizedBox(width: 10), + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Color(0xFF7DAFBC), + border: Border.all(color:Color(0xFF7DAFBC), width: 1.5), + ), + child: IconButton( + iconSize: 20, + icon: const Icon(Icons.arrow_forward, color: Colors.white), + onPressed: () { + tutorialCoachMark.previous(); + }, + ), + ), + ], + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + TargetContent( + padding: EdgeInsets.only(bottom: 0,top : 0,), + align: ContentAlign.top, + child: SizedBox( + width: MediaQuery.of(context).size.width, + height:MediaQuery.of(context).size.height*0.69 , + child: Stack( + children: [ + Positioned( + left: MediaQuery.of(context).size.width*0.40, + bottom: 0, + child: Image.asset( + 'assets/app_tour/leftUp.png', + width: 100, + height: 90, + ), + ), + ] + ), + + ), + ), + ], + ), + + + ]; } void _scrollToIndex(int index) { @@ -172,8 +761,8 @@ class _ChartScreen1State extends ConsumerState { filterDataSet = filterData.entries .map((entry) => {'key': entry.key, 'value': entry.value}) .toList(); - print("filterDataf1:- $filterData"); - print("filterDataf11:- $filterDataSet"); + // print("filterDataf1:- $filterData"); + // print("filterDataf11:- $filterDataSet"); } else { filterDataSet = data['filterData'] ?? []; print('filterData not found!'); @@ -741,6 +1330,7 @@ class _ChartScreen1State extends ConsumerState { mainAxisAlignment: MainAxisAlignment.end, children: [ Row( + key: bookMarkKey, children: [ Text( context.translate( @@ -753,7 +1343,7 @@ class _ChartScreen1State extends ConsumerState { ), ), SizedBox(width: 5), - Icon(Icons.bookmark_add_outlined, + Icon(Icons.bookmarks_outlined, color: Colors.white, size: 18), ], ), @@ -838,6 +1428,7 @@ class _ChartScreen1State extends ConsumerState { Padding( padding: const EdgeInsets.all(3.34), child: GridView.builder( + key:cardKey, itemCount: cardData.length, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), 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 ab7cc0f0..6d6d6927 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 @@ -270,7 +270,7 @@ class EconomyStatsState extends ConsumerState { ref.read(homeTourProvider.notifier).state = true; ref.read(chartsTourProvider.notifier).state = false; debugPrint('Home Tutorial Finished'); - context.push('/marriages'); + context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments'); }, )..show(context: context); } else if (!previousHomeTour) { @@ -284,7 +284,7 @@ class EconomyStatsState extends ConsumerState { onFinish: () { ref.read(previousHomeTourProvider.notifier).state = true; debugPrint('Previous Home Tutorial Finished'); - context.push('/marriages'); + context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments'); }, )..show(context: context); } @@ -292,6 +292,7 @@ class EconomyStatsState extends ConsumerState { } void _initTarget(){ + final double screenWidth = MediaQuery.of(context).size.width; homeTargets=[ TargetFocus( identify: 'cardTopicKey', @@ -301,8 +302,8 @@ class EconomyStatsState extends ConsumerState { createTargetContent( text: AppLocalizations.of(context)!.home_topic, alignment: ContentAlign.bottom, - gap: 45, - space: 40, + gap:0, + space: 44, ), TargetContent( align: ContentAlign.bottom, @@ -376,24 +377,19 @@ class EconomyStatsState extends ConsumerState { ), ), TargetContent( + padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0), align: ContentAlign.bottom, - child: SizedBox( - width: MediaQuery.of(context).size.width, - height:MediaQuery.of(context).size.height*0.69 , + child: Container( + width: 200, + height: 77, child: Stack( - children: [ - Positioned( - left: MediaQuery.of(context).size.width*0.4, - top: _imageCardPosition.dy-29, - child: Image.asset( - 'assets/app_tour/down_right.png', - width: 40, - height: 90, - ), - ), - ] + children: [ + Image.asset( + 'assets/app_tour/right_down.png', + fit: BoxFit.contain, + ), + ], ), - ), ), ], @@ -407,7 +403,7 @@ class EconomyStatsState extends ConsumerState { text:AppLocalizations.of(context)!.economy, alignment: ContentAlign.bottom, gap: 0, - space: 40,), + space: 44,), TargetContent( align: ContentAlign.bottom, @@ -425,7 +421,7 @@ class EconomyStatsState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ElevatedButton( - onPressed: () =>handleSkip, + onPressed: () =>handleSkip(), style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), @@ -494,24 +490,19 @@ class EconomyStatsState extends ConsumerState { ), ), TargetContent( + padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0), align: ContentAlign.bottom, - child: SizedBox( - width: MediaQuery.of(context).size.width , - height:MediaQuery.of(context).size.height*0.69 , + child: Container( + width: 200, + height: 77, child: Stack( - children: [ - Positioned( - left: MediaQuery.of(context).size.width*0.40, - top: _imageTopicPosition.dy-29, - child: Image.asset( - 'assets/app_tour/down_right.png', - width: 40, - height: 90, - ), - ), - ] + children: [ + Image.asset( + 'assets/app_tour/right_down.png', + fit: BoxFit.contain, + ), + ], ), - ), ), ], @@ -520,6 +511,7 @@ class EconomyStatsState extends ConsumerState { } void _initPreviousTarget(){ + final double screenWidth = MediaQuery.of(context).size.width; previousHomeTargets=[ TargetFocus( identify: 'cardsKey', @@ -530,7 +522,7 @@ class EconomyStatsState extends ConsumerState { text:AppLocalizations.of(context)!.economy, alignment: ContentAlign.bottom, gap: 0, - space: 40,), + space: 44,), TargetContent( align: ContentAlign.bottom, child: @@ -617,24 +609,19 @@ class EconomyStatsState extends ConsumerState { ), ), TargetContent( + padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0), align: ContentAlign.bottom, - child: SizedBox( - width: MediaQuery.of(context).size.width, - height:MediaQuery.of(context).size.height*0.69 , + child: Container( + width: 200, + height: 77, child: Stack( - children: [ - Positioned( - left: MediaQuery.of(context).size.width*0.40, - top: _imageTopicPosition.dy-29, - child: Image.asset( - 'assets/app_tour/down_right.png', - width: 40, - height: 90, - ), - ), - ] + children: [ + Image.asset( + 'assets/app_tour/right_down.png', + fit: BoxFit.contain, + ), + ], ), - ), ), ], @@ -647,8 +634,8 @@ class EconomyStatsState extends ConsumerState { createTargetContent( text:AppLocalizations.of(context)!.home_topic, alignment: ContentAlign.bottom, - gap: 45, - space: 40, + gap: 0, + space: 44, ), TargetContent( align: ContentAlign.bottom, @@ -724,24 +711,19 @@ class EconomyStatsState extends ConsumerState { ), ), TargetContent( + padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0), align: ContentAlign.bottom, - child: SizedBox( - width: MediaQuery.of(context).size.width, - height:MediaQuery.of(context).size.height*0.69 , + child: Container( + width: 200, + height: 77, child: Stack( - children: [ - Positioned( - left: MediaQuery.of(context).size.width*0.4, - top: _imageCardPosition.dy-29, - child: Image.asset( - 'assets/app_tour/down_right.png', - width: 40, - height: 90, - ), - ), - ] + children: [ + Image.asset( + 'assets/app_tour/right_down.png', + fit: BoxFit.contain, + ), + ], ), - ), ), ], diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart new file mode 100644 index 00000000..75e2ccbd --- /dev/null +++ b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart @@ -0,0 +1,194 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; + + +class BookMark extends ConsumerStatefulWidget { + const BookMark({super.key}); + + @override + ConsumerState createState() => _BookMarkState(); +} + +class _BookMarkState extends ConsumerState { + // Example dynamic data + final List> dataList = [ + { + 'title': 'GDP(Constant)', + 'subtitle': '(2022)(AED)', + 'value': '1.62T', + 'valueColor': Color(0xFF80A8CD), + 'isBookmark': true + }, + { + 'title': 'Trade Value', + 'subtitle': '(Jan-Jan 2024)-AED', + 'value': '215.4B', + 'valueColor': Color(0xFF80A8CD), + 'isBookmark': true + }, + { + 'title': 'Electricity Production', + 'subtitle': '(2022) (GWh)', + 'value': '155,438', + 'valueColor': Color(0xFFAA8E83), + 'isBookmark': true + }, + { + 'title': 'Crude Oil Production', + 'subtitle': '(2022) (1000 b/d)', + 'value': '3,064', + 'valueColor': Color(0xFF80A8CD), + 'isBookmark': true + }, + { + 'title': 'Quantitiy of Export Oil', + 'subtitle': '(2022) (1000 b/d)', + 'value': '2717', + 'valueColor': Color(0xFF7DAFBC), + 'isBookmark': true + }, + { + 'title': 'Desalinated Water Production', + 'subtitle': '(2022) (MCM)', + 'value': '1823.8', + 'valueColor': Color(0xFF7DAFBC), + 'isBookmark': true + }, + ]; + + @override + Widget build(BuildContext context) { + final filteredList = dataList.where((item) => item['isBookmark'] == true) + .toList(); + return BaseScaffold( + title: Text('Bookmark'), + body: Padding( + padding: const EdgeInsets.all(8.0), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, // Two columns + crossAxisSpacing: 10.0, + mainAxisSpacing: 10.0, + mainAxisExtent: 100, + ), + itemCount: filteredList.length, + itemBuilder: (context, index) { + return _buildBox(filteredList[index], context); + }, + ), + ), + ); + } + + // Widget for creating a box + Widget _buildBox(Map data, BuildContext context) { + return GestureDetector( + onTap: () { + debugPrint("Box clicked: ${data['title']}"); + }, + child: Container( + width: MediaQuery + .of(context) + .size + .width * 0.4, + height: 100, + padding: EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + border: Border.all(color: data['valueColor']), + ), + child: Stack( + children: [ + Align( + alignment: Alignment.center, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Align( + alignment: Alignment.center, + child: Text( + data['title'] ?? '', + style: TextStyle( + fontWeight: FontWeight.w500, + ), + overflow: TextOverflow.ellipsis, + // Truncate long text + maxLines: 1, // Limit to 1 line + ), + ), + ), + GestureDetector( + onTap: () { + debugPrint("Icon clicked in: ${data['title']}"); + setState(() { + // Change isOpen to false when icon is clicked + int index = dataList.indexWhere( + (item) => item['title'] == data['title'],); + if (index != -1) { + dataList[index]['isBookmark'] = false; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Removed From Bookmark', + style: TextStyle(color: Color(0xFF2F692C), + fontWeight: FontWeight.w600), + ), + backgroundColor: Color(0xFFD6E9C6), + duration: Duration(seconds: 2), + ), + ); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Failed to Remove', + style: TextStyle(color: Color(0xFFEB5F24), + fontWeight: FontWeight.w600), + ), + backgroundColor: Color(0xFF544C4C), + duration: Duration(seconds: 2), + ), + ); + } + }); + }, + child: Icon( + Icons.bookmarks_rounded, + color: Colors.black, + size: 20, + ), + ), + ], + ), + Text( + data['subtitle'] ?? '', + style: TextStyle( + fontWeight: FontWeight.w500, color: Colors.grey), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + Text( + data['value'] ?? '', + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: data['valueColor'], + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart index fbaff1ef..c75e9333 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -683,7 +683,7 @@ class _EditProfileState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - 'Date of Birth*', + AppLocalizations.of(context)!.dob, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 6394c770..48492269 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -189,7 +189,7 @@ class _BaseScaffoldState extends ConsumerState { .read(previousChartsTourProvider .notifier) .state = false; - context.push('/marriages'); + context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments'); }, ), ), @@ -746,6 +746,11 @@ class _BaseScaffoldState extends ConsumerState { ), onTap: () => context.go('/manageuser'), ), + ListTile( + leading: Icon(Icons.collections_bookmark_rounded), + title: const Text('Bookmark'), + onTap: () => context.go('/bookmark'), + ), ListTile( leading: Icon(Icons.book), title: const Text('User Guide'), diff --git a/pubspec.lock b/pubspec.lock index 99484f5b..f56d59cd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,23 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "76.0.0" + version: "72.0.0" _macros: dependency: transitive description: dart source: sdk - version: "0.3.3" + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "6.11.0" + version: "6.7.0" analyzer_plugin: dependency: transitive description: @@ -210,10 +210,10 @@ packages: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.18.0" connectivity_plus: dependency: "direct main" description: @@ -306,10 +306,10 @@ packages: dependency: transitive description: name: custom_lint_visitor - sha256: bfe9b7a09c4775a587b58d10ebb871d4fe618237639b1e84d5ec62d7dfef25f9 + sha256: "8aeb3b6ae2bb765e7716b93d1d10e8356d04e0ff6d7592de6ee04e0dd7d6587d" url: "https://pub.dev" source: hosted - version: "1.0.0+6.11.0" + version: "1.0.0+6.7.0" dart_style: dependency: transitive description: @@ -433,10 +433,10 @@ packages: dependency: "direct main" description: name: fl_chart - sha256: "5276944c6ffc975ae796569a826c38a62d2abcf264e26b88fa6f482e107f4237" + sha256: "74959b99b92b9eebeed1a4049426fd67c4abc3c5a0f4d12e2877097d6a11ae08" url: "https://pub.dev" source: hosted - version: "0.70.2" + version: "0.69.2" flutter: dependency: "direct main" description: flutter @@ -837,18 +837,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -877,10 +877,10 @@ packages: dependency: transitive description: name: macros - sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" url: "https://pub.dev" source: hosted - version: "0.1.3-main.0" + version: "0.1.2-main.4" mailer: dependency: "direct main" description: @@ -1268,7 +1268,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.0" + version: "0.0.99" smart_api_client: dependency: "direct main" description: @@ -1352,10 +1352,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.11.1" state_notifier: dependency: transitive description: @@ -1384,10 +1384,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.2.0" syncfusion_flutter_charts: dependency: "direct main" description: @@ -1424,10 +1424,10 @@ packages: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "0.7.2" the_validator: dependency: "direct main" description: @@ -1592,10 +1592,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.3.0" + version: "14.2.5" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0506e766..68b42804 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: riverpod_annotation: ^2.3.3 cupertino_icons: ^1.0.6 - fl_chart: ^0.70.2 + fl_chart: ^0.69.2 tutorial_coach_mark: ^1.2.12 marquee: ^2.2.3 url_launcher: ^6.3.1