app code add
This commit is contained in:
parent
349374a87d
commit
cb30850760
BIN
assets/app_tour/down_right.png
Normal file
BIN
assets/app_tour/down_right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
assets/app_tour/leftDown.png
Normal file
BIN
assets/app_tour/leftDown.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
assets/app_tour/leftUp.png
Normal file
BIN
assets/app_tour/leftUp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@ -82,5 +82,13 @@
|
||||
"password_between_8_to_40": "يجب أن تتراوح كلمة المرور بين 8 و64 حرفًا",
|
||||
"new_password_required": "كلمة المرور الجديدة مطلوبة",
|
||||
"old_password_is_required": "كلمة المرور القديمة مطلوبة",
|
||||
"confirm_password_is_required": "تأكيد كلمة المرور مطلوب"
|
||||
"confirm_password_is_required": "تأكيد كلمة المرور مطلوب",
|
||||
|
||||
"kpiCards": "يمكنك عرض بطاقات مؤشرات الأداء الرئيسية التفاعلية والرسوم البيانية لاستكشاف اتجاهات البيانات ومقارنة المقاييس الرئيسية بصريًا",
|
||||
"home_topic": "اختر أي فئة (على سيبل المثال : الاقتصاد، الاجتماعية، البيئة) لاستكشاف مؤشرات الأداء الرئيسية التفصيلية ، التصورات، ورؤى البيانات .",
|
||||
"economy": "يمكنك الوصول إلى الإحصائيات التفصيلية وصفحات التحليل لمؤشرات الأداء الرئيسية في فئة الاقتصاد لاكتشاف الاتجاهات والمقاييس الرئيسية .",
|
||||
"bookMark": "يمكنك وضع إشارة مرجعية على مؤشرات الأداء الرئيسية أو مجموعات البيانات المهمة للوصول السريع والسهل في أي وقت من خلال قسم الإشارات المرجعية. ",
|
||||
"toggle": "يمكنك التبديل بين اللغتين الإنجليزية والعربية باستخدام مفتاح تبديل اللغة في الزاوية اليمنى العليا للحصول على تجربة ثنائية اللغة.",
|
||||
"tour_navBar": "يمكنك استخدام شريط التنقل للوصول السريع إلى الملف الشخصي ,التعليقات , دليل المستخدم , الإشعارات والميزات الأساسية الأخرى للتطبيق.",
|
||||
"mainMenu": "يمكنك الوصول إلى الصفحات المخصصة والميزات الإضافية عن طريق تحديد الخيارات من القائمة الرئيسية."
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
"enter_your_password": "Enter your password",
|
||||
"register_Confirm_password": "Confirm password",
|
||||
"agree": "I agree to ",
|
||||
"t_and": "and",
|
||||
"t_and": " and ",
|
||||
"conditions": " of Fcsc",
|
||||
"terms_conditions": "terms & conditions",
|
||||
"privacy_policy":"privacy policy",
|
||||
@ -83,5 +83,13 @@
|
||||
"password_between_8_to_40": "Password must be between 8 and 64 characters",
|
||||
"new_password_required": "New password is required",
|
||||
"old_password_is_required": "Old password is required",
|
||||
"confirm_password_is_required": "Confirm password is required"
|
||||
"confirm_password_is_required": "Confirm password is required",
|
||||
|
||||
"kpiCards": "View interactive KPI cards and graphs to explore data trends and compare key metrics visually.",
|
||||
"home_topic": "Tap on any category (e.g., Economy, Social, Environment) to explore detailed KPIs, visualizations, and data insights.",
|
||||
"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."
|
||||
}
|
||||
|
||||
@ -1,12 +1,626 @@
|
||||
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/presentation/components/constant/constant.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart';
|
||||
|
||||
|
||||
class Marriages extends StatelessWidget {
|
||||
class Marriages extends ConsumerStatefulWidget {
|
||||
const Marriages({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<Marriages> createState() => _MarriagesState();
|
||||
}
|
||||
|
||||
class _MarriagesState extends ConsumerState<Marriages> {
|
||||
late List<TargetFocus> marriageTargets;
|
||||
late List<TargetFocus> previousMarriageTargets;
|
||||
late TutorialCoachMark tutorialCoachMark;
|
||||
final GlobalKey chartKey = GlobalKey();
|
||||
final GlobalKey bookMarkKey = GlobalKey();
|
||||
late double cardHeight= 0;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_calculateMarkPosition();
|
||||
_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() {
|
||||
|
||||
|
||||
_initmarriageTargets();
|
||||
tutorialCoachMark = TutorialCoachMark(
|
||||
paddingFocus: 0,
|
||||
useSafeArea: true,
|
||||
pulseEnable: false,
|
||||
hideSkip: true,
|
||||
targets: marriageTargets,
|
||||
onClickTarget: (target) {
|
||||
if (target.identify == 'chartKey') {
|
||||
// Scroll to the long widget
|
||||
Scrollable.ensureVisible(
|
||||
chartKey.currentContext!,
|
||||
duration: Duration(milliseconds: 500),
|
||||
);
|
||||
}
|
||||
},
|
||||
onFinish: () {
|
||||
context.push('/myhomepage');
|
||||
debugPrint('Marriage Tutorial Finished');
|
||||
},
|
||||
|
||||
)..show(context: context);
|
||||
|
||||
}
|
||||
void _previousKpiTutorial() {
|
||||
|
||||
_initpreviousTargets();
|
||||
tutorialCoachMark = TutorialCoachMark(
|
||||
paddingFocus: 0,
|
||||
useSafeArea: true,
|
||||
pulseEnable: false,
|
||||
hideSkip: true,
|
||||
targets: previousMarriageTargets,
|
||||
onFinish: () {
|
||||
context.push('/myhomepage');
|
||||
debugPrint('Previous Marriage Tutorial Finished');
|
||||
},
|
||||
|
||||
)..show(context: context);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void _startTutorialAfterRender() {
|
||||
final chartTour = ref.watch(chartsTourProvider);
|
||||
final previousChartTour = ref.watch(previousChartsTourProvider);
|
||||
if (chartKey.currentContext != null && !chartTour) {
|
||||
_kpiTutorialCoachMark();
|
||||
} else if(!previousChartTour) {
|
||||
_previousKpiTutorial();
|
||||
}
|
||||
else if (!chartTour || !previousChartTour){
|
||||
Future.delayed(Duration(milliseconds: 100), _startTutorialAfterRender);
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _calculateMarkPosition() {
|
||||
final RenderBox cardRenderBox = bookMarkKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final Size cardSize = cardRenderBox.size;
|
||||
cardHeight = cardSize.height;
|
||||
debugPrint('height : $cardHeight');
|
||||
}
|
||||
|
||||
void _initmarriageTargets(){
|
||||
final double screenWidth= MediaQuery.of(context).size.width;
|
||||
final double screenHeight= MediaQuery.of(context).size.height;
|
||||
marriageTargets=[
|
||||
TargetFocus(
|
||||
identify: 'chartsKey',
|
||||
keyTarget: chartKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text: AppLocalizations.of(context)!.kpiCards,
|
||||
alignment: ContentAlign.top,
|
||||
gap:50,
|
||||
space: 0,
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height*0.3,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 25,
|
||||
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,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text: AppLocalizations.of(context)!.bookMark,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 23,
|
||||
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: cardHeight+20),
|
||||
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: cardHeight+20),
|
||||
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: 'chartsKey',
|
||||
keyTarget: chartKey,
|
||||
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.3,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 30,
|
||||
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,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double myheight = MediaQuery.of(context).size.height;
|
||||
@ -33,7 +647,7 @@ class Marriages extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
IconButton(onPressed: (){}, icon: Icon(Icons.bookmark_add_outlined,color: Colors.white,size: 40,)),
|
||||
IconButton(key :bookMarkKey,onPressed: (){}, icon: Icon(Icons.bookmark_add_outlined,color: Colors.white,size: 40,)),
|
||||
IconButton(onPressed: (){}, icon: Icon(Icons.share,color: Colors.white,size: 30,)),
|
||||
],),
|
||||
],
|
||||
@ -47,6 +661,7 @@ class Marriages extends StatelessWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
key:chartKey,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Container(height: myheight/3.5,width: mywidth/2.5,
|
||||
|
||||
50
lib/presentation/Screens/app_tour/Target_content.dart
Normal file
50
lib/presentation/Screens/app_tour/Target_content.dart
Normal file
@ -0,0 +1,50 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final allTargetsCompletedProvider = StateProvider<bool>((ref) => true);
|
||||
final chartsTourProvider = StateProvider<bool>((ref) => true);
|
||||
final previousChartsTourProvider = StateProvider<bool>((ref) => true);
|
||||
final homeTourProvider = StateProvider<bool>((ref) => false);
|
||||
final previousHomeTourProvider = StateProvider<bool>((ref) => true);
|
||||
final scaffoldTourProvider = StateProvider<bool>((ref) => true);
|
||||
final previousScaffoldTourProvider = StateProvider<bool>((ref) => true);
|
||||
|
||||
TargetContent createTargetContent({
|
||||
required String text,
|
||||
required ContentAlign alignment,
|
||||
required double gap,
|
||||
required double space ,
|
||||
}) {
|
||||
return TargetContent(
|
||||
align: alignment,
|
||||
builder: (context, controller) {
|
||||
return Stack(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 10, bottom: space , top: space ),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
SizedBox(height: gap,),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -163,8 +163,12 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '../../drawer_routes/custom_drawer_routes.dart';
|
||||
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
||||
import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@ -215,26 +219,571 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
}
|
||||
}
|
||||
|
||||
class EconomyStatsWidget extends StatefulWidget {
|
||||
class EconomyStatsWidget extends ConsumerStatefulWidget {
|
||||
const EconomyStatsWidget({super.key});
|
||||
|
||||
@override
|
||||
EconomyStatsState createState() => EconomyStatsState();
|
||||
}
|
||||
|
||||
class EconomyStatsState extends State<EconomyStatsWidget> {
|
||||
class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
List<dynamic> data = [];
|
||||
|
||||
bool isLoading = true;
|
||||
|
||||
final GlobalKey cardTopicKey = GlobalKey();
|
||||
final GlobalKey cardsKey = GlobalKey();
|
||||
late TutorialCoachMark tutorialCoachMark;
|
||||
late List<TargetFocus> homeTargets;
|
||||
late List<TargetFocus> previousHomeTargets;
|
||||
Offset _imageCardPosition =Offset.zero;
|
||||
Offset _imageTopicPosition =Offset.zero;
|
||||
|
||||
void _calculateCardPosition() {
|
||||
final RenderBox cardRenderBox = cardsKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final Offset cardPosition = cardRenderBox.localToGlobal(Offset.zero);
|
||||
final Size cardSize = cardRenderBox.size;
|
||||
|
||||
// Calculate the position for the image
|
||||
final double imageX = cardPosition.dx + cardSize.width / 2;
|
||||
final double imageY = cardPosition.dy + cardSize.height;
|
||||
|
||||
setState(() {
|
||||
_imageCardPosition = Offset(imageX, imageY);
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//Method waits app tour to render Targets
|
||||
void _starTourRender() {
|
||||
if (cardTopicKey.currentContext != null) {
|
||||
_showHomeTour();
|
||||
} else {
|
||||
Future.delayed(Duration(milliseconds: 100), _starTourRender);
|
||||
}
|
||||
}
|
||||
|
||||
//Method to Start App Tour
|
||||
void _showHomeTour() {
|
||||
final homeTour = ref.watch(homeTourProvider);
|
||||
final previousHomeTour = ref.watch(previousHomeTourProvider);
|
||||
|
||||
// Check and show tutorials
|
||||
if (!homeTour) {
|
||||
// Show Home Tour
|
||||
_initTarget();
|
||||
_calculateCardPosition();
|
||||
tutorialCoachMark = TutorialCoachMark(
|
||||
paddingFocus: 0,
|
||||
useSafeArea: true,
|
||||
pulseEnable: false,
|
||||
hideSkip: true,
|
||||
targets: homeTargets,
|
||||
onFinish: () {
|
||||
ref.read(homeTourProvider.notifier).state = true;
|
||||
ref.read(chartsTourProvider.notifier).state = false;
|
||||
debugPrint('Home Tutorial Finished');
|
||||
context.push('/marriages');
|
||||
},
|
||||
)..show(context: context);
|
||||
} else if (!previousHomeTour) {
|
||||
_initPreviousTarget();
|
||||
tutorialCoachMark = TutorialCoachMark(
|
||||
paddingFocus: 0,
|
||||
useSafeArea: true,
|
||||
pulseEnable: false,
|
||||
hideSkip: true,
|
||||
targets: previousHomeTargets,
|
||||
onFinish: () {
|
||||
ref.read(previousHomeTourProvider.notifier).state = true;
|
||||
debugPrint('Previous Home Tutorial Finished');
|
||||
context.push('/marriages');
|
||||
},
|
||||
)..show(context: context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _initTarget(){
|
||||
homeTargets=[
|
||||
TargetFocus(
|
||||
identify: 'cardTopicKey',
|
||||
keyTarget: cardTopicKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text: AppLocalizations.of(context)!.home_topic,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 45,
|
||||
space: 40,
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height*0.69,
|
||||
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(
|
||||
'1/7',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(width: 10),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xFF7DAFBC),
|
||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1),
|
||||
),
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
iconSize: 20,
|
||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.next();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
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.4,
|
||||
top: _imageCardPosition.dy-29,
|
||||
child: Image.asset(
|
||||
'assets/app_tour/down_right.png',
|
||||
width: 40,
|
||||
height: 90,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TargetFocus(
|
||||
identify: 'cardsKey',
|
||||
keyTarget: cardsKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text:AppLocalizations.of(context)!.economy,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 0,
|
||||
space: 40,),
|
||||
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child:
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height *0.5, // Set an appropriate height for the Stack
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 25,
|
||||
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(
|
||||
'2/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: () {
|
||||
tutorialCoachMark.next();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
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,
|
||||
top: _imageTopicPosition.dy-29,
|
||||
child: Image.asset(
|
||||
'assets/app_tour/down_right.png',
|
||||
width: 40,
|
||||
height: 90,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
void _initPreviousTarget(){
|
||||
previousHomeTargets=[
|
||||
TargetFocus(
|
||||
identify: 'cardsKey',
|
||||
keyTarget: cardsKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text:AppLocalizations.of(context)!.economy,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 0,
|
||||
space: 40,),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child:
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height *0.5, // Set an appropriate height for the Stack
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 25,
|
||||
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(
|
||||
'2/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(
|
||||
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(previousHomeTourProvider.notifier).state=true;
|
||||
ref.read(chartsTourProvider.notifier).state=false;
|
||||
tutorialCoachMark.finish();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
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,
|
||||
top: _imageTopicPosition.dy-29,
|
||||
child: Image.asset(
|
||||
'assets/app_tour/down_right.png',
|
||||
width: 40,
|
||||
height: 90,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TargetFocus(
|
||||
identify: 'cardTopicKey',
|
||||
keyTarget: cardTopicKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text:AppLocalizations.of(context)!.home_topic,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 45,
|
||||
space: 40,
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height*0.69,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 35,
|
||||
left: 16,
|
||||
right: 16,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
tutorialCoachMark.skip();
|
||||
debugPrint('Skip clicked');
|
||||
},
|
||||
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(
|
||||
'1/7',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Row(
|
||||
children: [
|
||||
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(
|
||||
align: ContentAlign.bottom,
|
||||
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.4,
|
||||
top: _imageCardPosition.dy-29,
|
||||
child: Image.asset(
|
||||
'assets/app_tour/down_right.png',
|
||||
width: 40,
|
||||
height: 90,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
fetchData();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_starTourRender();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> fetchData() async {
|
||||
const baseUrl = 'https://pb.venbait.in/api/getHomePageData';
|
||||
const baseUrl = 'https://pb.venbait.in/api/getHomePageData?language=en';
|
||||
try {
|
||||
final response = await http.get(Uri.parse(baseUrl));
|
||||
if (response.statusCode == 200) {
|
||||
@ -336,6 +885,9 @@ class EconomyStatsState extends State<EconomyStatsWidget> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
RoundedCornerContainer(
|
||||
key: mainTopic['main_topic'] =='ECONOMY'
|
||||
? cardTopicKey
|
||||
: null,
|
||||
text: mainTopic['main_topic'],
|
||||
backgroundColor: backgroundColor,
|
||||
textStyle: const TextStyle(
|
||||
@ -347,6 +899,9 @@ class EconomyStatsState extends State<EconomyStatsWidget> {
|
||||
SizedBox(
|
||||
height: myheight / 4.8, // Set dynamic height
|
||||
child: Container(
|
||||
key:mainTopic['main_topic'] == 'ECONOMY'
|
||||
? cardsKey
|
||||
: null,
|
||||
// color: Colors.grey[200], // Set a background color for the scrollable container
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
|
||||
@ -6,9 +6,11 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
||||
|
||||
import '../../components/indicators/locale_provider.dart';
|
||||
import '../../components/my_toggle.dart';
|
||||
import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
import 'package:uae_stat/presentation/components/my_toggle.dart';
|
||||
|
||||
class BaseScaffold extends ConsumerStatefulWidget {
|
||||
final Widget body;
|
||||
@ -48,11 +50,447 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
String? collectionIds;
|
||||
|
||||
String? collectionId;
|
||||
late TutorialCoachMark tutorialCoachMark;
|
||||
late List<TargetFocus> appBarTargets;
|
||||
final GlobalKey bottomNavKey = GlobalKey();
|
||||
final GlobalKey toggleKey = GlobalKey();
|
||||
final GlobalKey drawerKey = GlobalKey();
|
||||
late double toggleHeight=0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_checkUserId();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_startAppbarTour();
|
||||
});
|
||||
}
|
||||
//Method to Start App Tour
|
||||
void _startAppbarTour() {
|
||||
final scaffoldProvider = ref.watch(scaffoldTourProvider);
|
||||
_calculatetooglePosition();
|
||||
if (!scaffoldProvider) {
|
||||
// Show Home Tour
|
||||
_initTarget();
|
||||
tutorialCoachMark = TutorialCoachMark(
|
||||
paddingFocus: 0,
|
||||
useSafeArea: true,
|
||||
pulseEnable: false,
|
||||
hideSkip: true,
|
||||
targets: appBarTargets, // Ensure `homeTargets` is defined for Home Tour
|
||||
onFinish: () {
|
||||
ref.read(homeTourProvider.notifier).state = true;
|
||||
debugPrint('Home Tutorial Finished');
|
||||
},
|
||||
)..show(context: context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _calculatetooglePosition() {
|
||||
final RenderBox cardRenderBox = toggleKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final Offset cardPosition = cardRenderBox.localToGlobal(Offset.zero);
|
||||
final Size cardSize = cardRenderBox.size;
|
||||
toggleHeight = cardSize.height;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void _initTarget(){
|
||||
final double screenWidth= MediaQuery.of(context).size.width;
|
||||
final double screenHeight= MediaQuery.of(context).size.height;
|
||||
appBarTargets=[
|
||||
TargetFocus(
|
||||
identify: 'bottomNav',
|
||||
keyTarget: bottomNavKey,
|
||||
shape: ShapeLightFocus.RRect, // Rounded rectangle highlight
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text: AppLocalizations.of(context)!.tour_navBar,
|
||||
alignment: ContentAlign.top,
|
||||
space: 0,
|
||||
gap: 100,
|
||||
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.top,
|
||||
child:
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height* 0.30, // Set an appropriate height for the Stack
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 25,
|
||||
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(
|
||||
'5/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(
|
||||
icon: const Icon(Icons.arrow_back, color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.finish();
|
||||
ref.read(scaffoldTourProvider.notifier).state=true;
|
||||
ref.read(previousChartsTourProvider.notifier).state=false;
|
||||
context.push('/marriages');
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xFF7DAFBC),
|
||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1.5),
|
||||
),
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.next();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
TargetContent(
|
||||
padding: EdgeInsets.only(left:screenWidth*0.4, bottom: 0 ),
|
||||
align: ContentAlign.top,
|
||||
child: Container(
|
||||
width: 200,
|
||||
height: 100,
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/app_tour/leftUp.png',
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TargetFocus(
|
||||
identify: 'drawerKey',
|
||||
keyTarget: drawerKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
radius: 0, // No rounded corners
|
||||
paddingFocus: 1, // Rounded rectangle highlight
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text: AppLocalizations.of(context)!.mainMenu,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 55,
|
||||
space: 0,
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child:
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height* 0.80, // Set an appropriate height for the Stack
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 25,
|
||||
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(
|
||||
'6/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(
|
||||
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(
|
||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.next();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
TargetContent(
|
||||
padding: EdgeInsets.only(right: screenWidth*0.7, top: toggleHeight-5),
|
||||
align: ContentAlign.right,
|
||||
child: Container(
|
||||
width: 200,
|
||||
height: screenHeight/4,
|
||||
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: 'toggleKey',
|
||||
keyTarget: toggleKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
radius: 0,
|
||||
paddingFocus: 0,// Rounded rectangle highlight
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text: AppLocalizations.of(context)!.toggle,
|
||||
space: 0,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 50,
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child:
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height* 0.80,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 25,
|
||||
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(
|
||||
'7/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(
|
||||
icon: const Icon(Icons.arrow_back, color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.previous();
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
debugPrint('Got it 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;
|
||||
tutorialCoachMark.finish();
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
side: const BorderSide(color: Colors.white),
|
||||
backgroundColor: Colors.white,
|
||||
elevation: 0,
|
||||
),
|
||||
child: const Text(
|
||||
'Got it',
|
||||
style: TextStyle(
|
||||
color: Color(0xFF7DAFBC),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
TargetContent(
|
||||
padding: EdgeInsets.only(left:screenWidth*0.7, top: toggleHeight),
|
||||
align: ContentAlign.left,
|
||||
child: Container(
|
||||
width: 200,
|
||||
height: screenHeight/4,
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/app_tour/down_right.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,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
// Method to retrieve userId from SharedPreferences
|
||||
@ -221,7 +659,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
// onPressed: () {},
|
||||
// icon: const Icon(Icons.toggle_off_outlined),
|
||||
// ),
|
||||
MyToggle(isOn: locale?.languageCode == 'en',
|
||||
MyToggle(
|
||||
key: toggleKey,
|
||||
isOn: locale?.languageCode == 'en',
|
||||
knobTextWhenOn: 'ع',
|
||||
knobTextWhenOff: 'EN',
|
||||
pathColorWhenOn: Colors.grey.shade300,
|
||||
@ -248,6 +688,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return IconButton(
|
||||
key:drawerKey,
|
||||
color: (widget.showBackButton == true)
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
@ -351,6 +792,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
key: bottomNavKey,
|
||||
currentIndex: _getSelectedIndex(currentRoute),
|
||||
onTap: (index) => _onItemTapped(context, index),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
|
||||
156
pubspec.lock
156
pubspec.lock
@ -5,31 +5,31 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "88399e291da5f7e889359681a8f64b18c5123e03576b01f32a6a276611e511c3"
|
||||
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "78.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: "62899ef43d0b962b056ed2ebac6b47ec76ffd003d5f7c4e4dc870afe63188e33"
|
||||
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
version: "6.7.0"
|
||||
analyzer_plugin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer_plugin
|
||||
sha256: "1d460d14e3c2ae36dc2b32cef847c4479198cf87704f63c3c3c8150ee50c3916"
|
||||
sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.0"
|
||||
version: "0.11.3"
|
||||
ansicolor:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -74,50 +74,50 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
|
||||
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
|
||||
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.1.1"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
sha256: "294a2edaf4814a378725bfe6358210196f5ea37af89ecd81bfa32960113d4948"
|
||||
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.3"
|
||||
version: "4.0.2"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
sha256: "99d3980049739a985cf9b21f30881f46db3ebc62c5b8d5e60e27440876b1ba1e"
|
||||
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.3"
|
||||
version: "2.4.2"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "74691599a5bc750dc96a6b4bfd48f7d9d66453eab04c7f4063134800d6a5c573"
|
||||
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.14"
|
||||
version: "2.4.13"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
|
||||
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
version: "7.3.2"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -186,10 +186,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:
|
||||
@ -258,42 +258,42 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: custom_lint
|
||||
sha256: "6d509673c4dd0baa90e60dc8366bc2acc6690f16a7d44bfae31294d82c5d2a62"
|
||||
sha256: "3486c470bb93313a9417f926c7dd694a2e349220992d7b9d14534dc49c15bba9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.1"
|
||||
version: "0.7.0"
|
||||
custom_lint_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: custom_lint_builder
|
||||
sha256: "8cc525c7b160eb47bb1ded8b2633c0f8b907930eb986ac577aded87cdd2835fe"
|
||||
sha256: "42cdc41994eeeddab0d7a722c7093ec52bd0761921eeb2cbdbf33d192a234759"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.1"
|
||||
version: "0.7.0"
|
||||
custom_lint_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: custom_lint_core
|
||||
sha256: "6dcee8a017181941c51a110da7e267c1d104dc74bec8862eeb8c85b5c8759a9e"
|
||||
sha256: "02450c3e45e2a6e8b26c4d16687596ab3c4644dd5792e3313aa9ceba5a49b7f5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.1"
|
||||
version: "0.7.0"
|
||||
custom_lint_visitor:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: custom_lint_visitor
|
||||
sha256: "14df0760dfa81b7b0c398c876045f4e4a343eb2c9d200c66163671dd3e337c1b"
|
||||
sha256: "8aeb3b6ae2bb765e7716b93d1d10e8356d04e0ff6d7592de6ee04e0dd7d6587d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0+7.1.0"
|
||||
version: "1.0.0+6.7.0"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac"
|
||||
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "2.3.7"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -565,10 +565,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: freezed
|
||||
sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c"
|
||||
sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.8"
|
||||
version: "2.5.7"
|
||||
freezed_annotation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -661,10 +661,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
version: "4.0.2"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -749,10 +749,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: injectable_generator
|
||||
sha256: b04673a4c88b3a848c0c77bf58b8309f9b9e064d9fe1df5450c8ee1675eaea1a
|
||||
sha256: af403d76c7b18b4217335e0075e950cd0579fd7f8d7bd47ee7c85ada31680ba1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
version: "2.6.2"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -789,10 +789,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: json_serializable
|
||||
sha256: b0a98230538fe5d0b60a22fb6bf1b6cb03471b53e3324ff6069c591679dd59c9
|
||||
sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.9.3"
|
||||
version: "6.9.0"
|
||||
jwt_decoder:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -805,18 +805,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:
|
||||
@ -829,10 +829,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
version: "5.0.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -845,10 +845,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:
|
||||
@ -1045,10 +1045,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
|
||||
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
version: "1.4.0"
|
||||
recase:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1077,10 +1077,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: riverpod_analyzer_utils
|
||||
sha256: "837a6dc33f490706c7f4632c516bcd10804ee4d9ccc8046124ca56388715fdf3"
|
||||
sha256: c6b8222b2b483cb87ae77ad147d6408f400c64f060df7a225b127f4afef4f8c8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.9"
|
||||
version: "0.5.8"
|
||||
riverpod_annotation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1093,18 +1093,18 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: riverpod_generator
|
||||
sha256: "120d3310f687f43e7011bb213b90a436f1bbc300f0e4b251a72c39bccb017a4f"
|
||||
sha256: "63546d70952015f0981361636bf8f356d9cfd9d7f6f0815e3c07789a41233188"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.4"
|
||||
version: "2.6.3"
|
||||
riverpod_lint:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: riverpod_lint
|
||||
sha256: b05408412b0f75dec954e032c855bc28349eeed2d2187f94519e1ddfdf8b3693
|
||||
sha256: "83e4caa337a9840469b7b9bd8c2351ce85abad80f570d84146911b32086fbd99"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.4"
|
||||
version: "2.6.3"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1196,10 +1196,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.2"
|
||||
version: "1.4.1"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1212,7 +1212,7 @@ packages:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
version: "0.0.99"
|
||||
smart_api_client:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1224,10 +1224,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b"
|
||||
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "1.5.0"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1256,10 +1256,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:
|
||||
@ -1288,10 +1288,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:
|
||||
@ -1320,10 +1320,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:
|
||||
@ -1340,6 +1340,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
tutorial_coach_mark:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: tutorial_coach_mark
|
||||
sha256: df450c88d4c812bc221afd3ff948da3dc0f44c0b4fa5dbc046d6d86f2cfc9e71
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.12"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1408,10 +1416,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
|
||||
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.3.3"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1448,10 +1456,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_android
|
||||
sha256: "7018dbcb395e2bca0b9a898e73989e67c0c4a5db269528e1b036ca38bcca0d0b"
|
||||
sha256: "391e092ba4abe2f93b3e625bd6b6a6ec7d7414279462c1c0ee42b5ab8d0a0898"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.17"
|
||||
version: "2.7.16"
|
||||
video_player_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1480,10 +1488,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:
|
||||
@ -1581,5 +1589,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.6.0 <4.0.0"
|
||||
flutter: ">=3.27.0"
|
||||
dart: ">=3.5.2 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
||||
@ -22,7 +22,7 @@ dependencies:
|
||||
cupertino_icons: ^1.0.6
|
||||
|
||||
fl_chart: ^0.69.2
|
||||
|
||||
tutorial_coach_mark: ^1.2.12
|
||||
marquee: ^2.2.3
|
||||
url_launcher: ^6.3.1
|
||||
# dynamic_layouts:
|
||||
@ -110,6 +110,7 @@ flutter:
|
||||
- assets/cached_responses/sharepoint/country_leader_imgs/
|
||||
- assets/edit_profile/
|
||||
- assets/splash_screen/
|
||||
- assets/app_tour/
|
||||
|
||||
fonts:
|
||||
- family: Segoe
|
||||
|
||||
Loading…
Reference in New Issue
Block a user