App Tour first time login and fiter change
This commit is contained in:
parent
b5d4df493e
commit
3ba3650e92
@ -15,12 +15,12 @@ if (localPropertiesFile.exists()) {
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = "6"
|
||||
flutterVersionCode = "7"
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = "1.0.5"
|
||||
flutterVersionName = "1.0.6"
|
||||
}
|
||||
|
||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||
|
||||
BIN
assets/icons/misc/vector.png
Normal file
BIN
assets/icons/misc/vector.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 557 B |
BIN
assets/icons/misc/visibility_off.png
Normal file
BIN
assets/icons/misc/visibility_off.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/icons/misc/visible_on.png
Normal file
BIN
assets/icons/misc/visible_on.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 818 B |
@ -328,16 +328,15 @@ final GoRouter router = GoRouter(
|
||||
GoRoute(
|
||||
path: '/',
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
builder: (context, state) => LoginRoute(),
|
||||
builder: (context, state) => LoginRoute(isLoginScreen: true),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/internetcheck',
|
||||
builder: (context, state) => InternetCheck(),
|
||||
|
||||
),
|
||||
GoRoute(
|
||||
path: '/login',
|
||||
builder: (context, state) => LoginRoute(),
|
||||
builder: (context, state) => LoginRoute(isLoginScreen: true),
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
),
|
||||
GoRoute(
|
||||
|
||||
@ -6,4 +6,7 @@ abstract class MiscIconAssetPath {
|
||||
static const menu = '$_basePath/menu.png';
|
||||
static const person = '$_basePath/person.png';
|
||||
static const back = '$_basePath/back.png';
|
||||
static const vector = '$_basePath/vector.png';
|
||||
static const visibleOn = '$_basePath/visible_on.png';
|
||||
static const visibilityOff = '$_basePath/visibility_off.png';
|
||||
}
|
||||
|
||||
@ -12,14 +12,16 @@
|
||||
"enter_your_email": "Enter your email",
|
||||
"enter_your_password": "Enter your password",
|
||||
"register_Confirm_password": "Confirm password",
|
||||
"agree": "I agree to ",
|
||||
"agree": "I agree to the",
|
||||
"t_and": " and ",
|
||||
"conditions": " of Fcsc",
|
||||
"terms_conditions": "terms & conditions",
|
||||
"privacy_policy":"privacy policy",
|
||||
"account_confirmation": "Already have an account? Login",
|
||||
"conditions": " of FCSC",
|
||||
"terms_conditions": "Terms & Conditions",
|
||||
"privacy_policy":"Privacy Policy",
|
||||
"account_confirmation": "Already have an account?",
|
||||
"login_title": "Login",
|
||||
|
||||
|
||||
|
||||
"profile_title": "Edit Profile",
|
||||
"my_profile": "My Profile",
|
||||
"logout": "Logout",
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import 'package:external_repos/external_repos.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:uae_stat/config/my_theme.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
|
||||
import 'package:uae_stat/presentation/Screens/profilepage.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
@ -471,14 +474,15 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
padding: const EdgeInsets.only(top: 5.0,bottom: 20, left: 20,right: 20),
|
||||
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: screenheight / 15),
|
||||
SizedBox(height: screenheight / 60),
|
||||
Text(
|
||||
// 'Register',
|
||||
AppLocalizations.of(context)!.register_title,
|
||||
@ -492,18 +496,42 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
// Display this if registration is pending approval
|
||||
TextFormField(
|
||||
controller: _usernameController,
|
||||
focusNode: _focusNodes[0],
|
||||
// focusNode: _focusNodes[0],
|
||||
decoration: InputDecoration(
|
||||
// hintText: _showHints[0] ? 'Username' : null,
|
||||
hintText: _showHints[0]
|
||||
? AppLocalizations.of(context)!.register_name
|
||||
: null,
|
||||
prefixIcon: Icon(
|
||||
Icons.person,
|
||||
color: Colors.blue,
|
||||
prefixIcon: Padding(
|
||||
padding: const EdgeInsets.all(8.0), // Adjust the padding as needed
|
||||
child: Image.asset(
|
||||
MiscIconAssetPath.person,
|
||||
color: Color(0xFF90B0D5),
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
|
||||
// prefixIcon: Icon(
|
||||
// Icons.person,
|
||||
// color: Color(0xFF90B0D5),
|
||||
//
|
||||
// ),
|
||||
// border: OutlineInputBorder(),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFF90B0D5), width: 2), // Enabled border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFFD83731), width: 1), // Error border
|
||||
),
|
||||
border: OutlineInputBorder(),
|
||||
counterText: '',
|
||||
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
||||
),
|
||||
validator: _validateUsername,
|
||||
maxLength:
|
||||
@ -513,7 +541,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
SizedBox(height: 15),
|
||||
TextFormField(
|
||||
controller: _emailController,
|
||||
focusNode: _focusNodes[1],
|
||||
// focusNode: _focusNodes[1],
|
||||
decoration: InputDecoration(
|
||||
// hintText: 'Enter your email',
|
||||
hintText: _showHints[1]
|
||||
@ -521,12 +549,30 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
.enter_your_email
|
||||
: null,
|
||||
// _showHints[1] ? 'Enter your email' : null,
|
||||
prefixIcon: Icon(
|
||||
Icons.email,
|
||||
color: Colors.blue,
|
||||
prefixIcon: Padding(
|
||||
padding: const EdgeInsets.all(8.0), // Adjust the padding as needed
|
||||
child: Image.asset(
|
||||
MiscIconAssetPath.vector,
|
||||
color: Color(0xFF90B0D5),
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
// border: OutlineInputBorder(),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFF90B0D5), width: 2), // Enabled border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFFD83731), width: 1), // Error border
|
||||
),
|
||||
border: OutlineInputBorder(),
|
||||
counterText: '',
|
||||
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
||||
),
|
||||
validator: _validateEmail,
|
||||
maxLength: 320,
|
||||
@ -539,7 +585,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
SizedBox(height: 15),
|
||||
TextFormField(
|
||||
controller: _passwordController,
|
||||
focusNode: _focusNodes[2],
|
||||
// focusNode: _focusNodes[2],
|
||||
obscureText: _obscurePassword,
|
||||
decoration: InputDecoration(
|
||||
hintText: _showHints[2]
|
||||
@ -547,25 +593,59 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
.enter_your_password
|
||||
: null,
|
||||
// _showHints[2] ? 'Enter your password' : null,
|
||||
prefixIcon: Icon(
|
||||
Icons.lock,
|
||||
color: Colors.blue,
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
_obscurePassword
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
color: Colors.blue,
|
||||
prefixIcon: Padding(
|
||||
padding: const EdgeInsets.all(8.0), // Adjust the padding as needed
|
||||
child: Image.asset(
|
||||
MiscIconAssetPath.lock,
|
||||
color: Color(0xFF90B0D5),
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
// prefixIcon: Icon(
|
||||
// Icons.lock,
|
||||
// color: Color(0xFF90B0D5),
|
||||
// ),
|
||||
suffixIcon: IconButton(
|
||||
// icon: Icon(
|
||||
// _obscurePassword
|
||||
// ? Icons.visibility_off
|
||||
// : Icons.visibility,
|
||||
// color: Color(0xFF9EA2A9),
|
||||
// ),
|
||||
|
||||
icon: Image.asset(
|
||||
_obscurePassword
|
||||
?MiscIconAssetPath.visibilityOff
|
||||
:MiscIconAssetPath.visibleOn,
|
||||
|
||||
color: Color(0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
|
||||
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_obscurePassword = !_obscurePassword;
|
||||
});
|
||||
},
|
||||
),
|
||||
border: OutlineInputBorder(),
|
||||
// border: OutlineInputBorder(),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFF90B0D5), width: 2), // Enabled border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFFD83731), width: 1), // Error border
|
||||
),
|
||||
counterText: '',
|
||||
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
||||
),
|
||||
validator: _validatePassword,
|
||||
maxLength: 40,
|
||||
@ -574,7 +654,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
SizedBox(height: 15),
|
||||
TextFormField(
|
||||
controller: _confirmpasswordController,
|
||||
focusNode: _focusNodes[3],
|
||||
// focusNode: _focusNodes[3],
|
||||
obscureText: _obscureConfirmPassword,
|
||||
decoration: InputDecoration(
|
||||
hintText: _showHints[3]
|
||||
@ -582,16 +662,25 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
.register_Confirm_password
|
||||
: null,
|
||||
// _showHints[3] ? 'Confirm password' : null,
|
||||
prefixIcon: Icon(
|
||||
Icons.lock,
|
||||
color: Colors.blue,
|
||||
prefixIcon: Padding(
|
||||
padding: const EdgeInsets.all(8.0), // Adjust the padding as needed
|
||||
child: Image.asset(
|
||||
MiscIconAssetPath.lock,
|
||||
color: Color(0xFF90B0D5),
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
|
||||
icon: Image.asset(
|
||||
_obscureConfirmPassword
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
color: Colors.blue,
|
||||
?MiscIconAssetPath.visibilityOff
|
||||
:MiscIconAssetPath.visibleOn,
|
||||
|
||||
color: Color(0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
@ -600,8 +689,23 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
});
|
||||
},
|
||||
),
|
||||
border: OutlineInputBorder(),
|
||||
// border: OutlineInputBorder(
|
||||
// borderSide: BorderSide(color: Colors.blue, width: 2), // Default border color
|
||||
// ),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFF90B0D5), width: 2), // Enabled border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(color: Color(0xFFD83731), width: 1), // Error border
|
||||
),
|
||||
counterText: '',
|
||||
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
||||
),
|
||||
validator: _validateConfirmPassword,
|
||||
maxLength: 40,
|
||||
@ -623,7 +727,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
});
|
||||
},
|
||||
side: BorderSide(
|
||||
color: showError ? Colors.red : Colors.grey,
|
||||
color: showError ? Colors.red : Color(0xFF92722A),
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
@ -637,7 +741,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
text: AppLocalizations.of(context)!
|
||||
.terms_conditions,
|
||||
// text: 'Terms & Conditions',
|
||||
style: TextStyle(color: Colors.blue),
|
||||
style: TextStyle( color: MyTheme.topicColor(IndicatorTopic.economy).shade600,),
|
||||
),
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(context)!
|
||||
@ -645,7 +749,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(context)!
|
||||
.privacy_policy,
|
||||
style: TextStyle(color: Colors.blue),
|
||||
style: TextStyle( color: MyTheme.topicColor(IndicatorTopic.economy).shade600,),
|
||||
),
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(context)!
|
||||
@ -695,8 +799,10 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
fontSize: 16, color: Colors.white),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(Icons.arrow_forward,
|
||||
color: Colors.white),
|
||||
const Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: Colors.white, // Set your desired color here
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -730,8 +836,10 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
fontSize: 16, color: Colors.white),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(Icons.arrow_forward,
|
||||
color: Colors.white),
|
||||
const Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: Colors.white, // Set your desired color here
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
@ -369,9 +369,15 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
child: ListView.builder(
|
||||
itemCount: filters.length,
|
||||
itemBuilder: (context, index) {
|
||||
filters.sort((a, b) => a["filter_text_and_order"]["order"]
|
||||
.compareTo(b["filter_text_and_order"]["order"]));
|
||||
|
||||
final filter = filters[index];
|
||||
final filterKey = filter["filter_key"];
|
||||
final filterData = filter["filter_data"];
|
||||
final filter_text_and_order =
|
||||
filter["filter_text_and_order"];
|
||||
final fieldOrder = filter_text_and_order['order'];
|
||||
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
@ -386,7 +392,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
capitalizeAndSplit(filterKey),
|
||||
context.translate(filter_text_and_order['en'],
|
||||
filter_text_and_order['ar']),
|
||||
// capitalizeAndSplit(filterKey),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -399,8 +407,13 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, dialogSetState) {
|
||||
final locale =
|
||||
ref.watch(localeProvider);
|
||||
print('localelocale $locale');
|
||||
return AlertDialog(
|
||||
title: Text('Select $filterKey'),
|
||||
title: Text(
|
||||
// "${locale == 'ar' ? 'يختار ' : 'Select '}"
|
||||
"${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}"),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: filterData
|
||||
@ -465,7 +478,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
children:
|
||||
selectedFilter["filter_data"].isEmpty
|
||||
? [
|
||||
Text('Select $filterKey',
|
||||
Text(
|
||||
// "${locale == 'ar' ? 'يختار ' : 'Select '}"
|
||||
"${context.translate(filter_text_and_order['en'], filter_text_and_order['ar'])}",
|
||||
style: TextStyle(
|
||||
color: Colors.grey))
|
||||
]
|
||||
@ -1023,26 +1038,31 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
Flexible(
|
||||
fit: FlexFit.loose,
|
||||
child: FittedBox(
|
||||
child: Text(
|
||||
'${chart_heading ?? 'NA'}',
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2, // Limit to 2 lines
|
||||
softWrap:
|
||||
true, // Enable soft wrapping
|
||||
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black87,
|
||||
child: SizedBox(
|
||||
// height: 70.0,
|
||||
child: Text(
|
||||
'${chart_heading ?? 'NA'}',
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2, // Limit to 2 lines
|
||||
softWrap:
|
||||
true, // Enable soft wrapping
|
||||
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
||||
style: TextStyle(
|
||||
fontSize: 8,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 1),
|
||||
Text(
|
||||
'(${data['lastYear'] ?? 'NA'})',
|
||||
style: const TextStyle(
|
||||
fontSize: 11, color: Colors.grey),
|
||||
fontSize: 10, color: Colors.grey),
|
||||
),
|
||||
const SizedBox(height: 1),
|
||||
Flexible(
|
||||
fit: FlexFit.loose,
|
||||
child: FittedBox(
|
||||
@ -1051,7 +1071,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
apiService.formatAmount(
|
||||
data['lastYearValue']),
|
||||
style: const TextStyle(
|
||||
fontSize: 26,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Color(0xFF90B0D5),
|
||||
),
|
||||
@ -1074,7 +1094,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
apiService.formatAmount(
|
||||
data['secondLastYearValue']),
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFFD83731),
|
||||
),
|
||||
@ -1084,7 +1104,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
Text(
|
||||
'(${data['secondLastYear'] ?? 'NA'})',
|
||||
style: const TextStyle(
|
||||
fontSize: 8,
|
||||
fontSize: 9,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey),
|
||||
),
|
||||
@ -1120,37 +1140,42 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
const SizedBox(height: 5),
|
||||
Flexible(
|
||||
fit: FlexFit.loose,
|
||||
child: FittedBox(
|
||||
child: Text(
|
||||
'${chart_heading ?? 'NA'}',
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2, // Limit to 2 lines
|
||||
softWrap:
|
||||
true, // Enable soft wrapping
|
||||
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black87,
|
||||
),
|
||||
// child: FittedBox(
|
||||
child: Text(
|
||||
'${chart_heading ?? 'NA'}',
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2, // Limit to 2 lines
|
||||
softWrap:
|
||||
true, // Enable soft wrapping
|
||||
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
||||
style: TextStyle(
|
||||
fontSize: 9,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
// ),
|
||||
),
|
||||
const SizedBox(height: 1),
|
||||
Text(
|
||||
'(${data['firstYear'] ?? 'NA'} - ${data['lastYear'] ?? 'NA'})',
|
||||
style: const TextStyle(
|
||||
fontSize: 10, color: Colors.grey),
|
||||
),
|
||||
const SizedBox(height: 1),
|
||||
Flexible(
|
||||
fit: FlexFit.loose,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.contain,
|
||||
child: Text(
|
||||
'${data['roundedAverage'] ?? 'NA'}',
|
||||
style: const TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Color(0xFF90B0D5),
|
||||
child: SizedBox(
|
||||
height: 50.0,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.contain,
|
||||
child: Text(
|
||||
'${data['roundedAverage'] ?? 'NA'}',
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Color(0xFF90B0D5),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -538,6 +538,7 @@ class ChartWidget extends StatelessWidget {
|
||||
color: groupColorMap[group],
|
||||
),
|
||||
SizedBox(width: 6),
|
||||
|
||||
Text(
|
||||
group,
|
||||
style: TextStyle(fontSize: 14),
|
||||
@ -789,12 +790,26 @@ class ChartWidget extends StatelessWidget {
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
interval: 1,
|
||||
getTitlesWidget: (value, meta) {
|
||||
if (value.toInt() < xAxisData.length) {
|
||||
String title = xAxisData[value.toInt()];
|
||||
String displayTitle = title.length > 10 ? title.substring(0, 10) + '...' : title;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(xAxisData[value.toInt()]),
|
||||
);
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: SizedBox(
|
||||
width: 60, // Limit width to force wrapping
|
||||
child: Transform.rotate(
|
||||
angle: -0.5,
|
||||
child:Tooltip(
|
||||
message: title,
|
||||
child: Text(
|
||||
displayTitle,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)),)
|
||||
));
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
@ -994,19 +1009,36 @@ class ChartWidget extends StatelessWidget {
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
reservedSize: 20, // Added space for rotated titles
|
||||
reservedSize: 40, // Added space for rotated titles
|
||||
getTitlesWidget: (value, meta) {
|
||||
if (value < groupByValues.length) {
|
||||
String title =
|
||||
groupByValues.elementAt(value.toInt());
|
||||
return Transform.rotate(
|
||||
angle:
|
||||
-0.5, // Rotation in radians (~ -30 degrees)
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
);
|
||||
|
||||
String displayTitle = title.length > 10 ? title.substring(0, 10) + '...' : title;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: SizedBox(
|
||||
width: 60, // Limit width to force wrapping
|
||||
child: Transform.rotate(
|
||||
angle: -0.5,
|
||||
child:Tooltip(
|
||||
message: title,
|
||||
child: Text(
|
||||
displayTitle,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)),)
|
||||
));
|
||||
// return Transform.rotate(
|
||||
// angle:
|
||||
// -0.5, // Rotation in radians (~ -30 degrees)
|
||||
// child: Text(
|
||||
// title,
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// ),
|
||||
// );
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
@ -1150,152 +1182,341 @@ class ChartWidget extends StatelessWidget {
|
||||
SizedBox(height: 10),
|
||||
// Chart
|
||||
Expanded(
|
||||
child: BarChart(
|
||||
BarChartData(
|
||||
maxY: 400000,
|
||||
rotationQuarterTurns: rotationTurns,
|
||||
barTouchData: BarTouchData(
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
tooltipHorizontalAlignment: FLHorizontalAlignment.center,
|
||||
// Only show tooltip when touched
|
||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
if (rod.toY == 0 || touchedGroupIndex == -1) {
|
||||
return null; // Don't show the tooltip if the value is 0 or there's no touch
|
||||
}
|
||||
|
||||
if (groupIndex == touchedGroupIndex) {
|
||||
// print('Group Index: $groupIndex, Group : $group');
|
||||
|
||||
// Get the group label dynamically
|
||||
String groupLabel = groupByValues.elementAt(groupIndex);
|
||||
|
||||
// Fetch the crop for the current group from groupedCrops
|
||||
String cropType = groupByValues.elementAt(groupIndex);
|
||||
String crop = groupedCrops[cropType]![rodIndex];
|
||||
double value = rod.toY;
|
||||
|
||||
String formattedValue;
|
||||
if (value >= 1000000) {
|
||||
formattedValue =
|
||||
(value / 1000000).toStringAsFixed(1) + 'M';
|
||||
} else if (value >= 1000) {
|
||||
formattedValue =
|
||||
(value / 1000).toStringAsFixed(1) + 'K';
|
||||
} else {
|
||||
formattedValue = value
|
||||
.toStringAsFixed(0); // for values smaller than 1000
|
||||
child: BarChart(
|
||||
BarChartData(
|
||||
maxY: 400000,
|
||||
rotationQuarterTurns: rotationTurns,
|
||||
barTouchData: BarTouchData(
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
tooltipHorizontalAlignment: FLHorizontalAlignment.center,
|
||||
tooltipRoundedRadius: 8,
|
||||
fitInsideHorizontally: true, // Ensure it fits within the screen
|
||||
fitInsideVertically: true,
|
||||
tooltipPadding: EdgeInsets.all(8),
|
||||
tooltipMargin: 16,
|
||||
// Only show tooltip when touched
|
||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
if (rod.toY == 0 || touchedGroupIndex == -1) {
|
||||
return null; // Don't show the tooltip if the value is 0 or there's no touch
|
||||
}
|
||||
|
||||
return BarTooltipItem(
|
||||
'$groupLabel\n$crop',
|
||||
const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' Value: $formattedValue',
|
||||
style: const TextStyle(
|
||||
color: Colors.yellow,
|
||||
fontWeight: FontWeight.w500,
|
||||
if (groupIndex == touchedGroupIndex) {
|
||||
// print('Group Index: $groupIndex, Group : $group');
|
||||
|
||||
// Get the group label dynamically
|
||||
String groupLabel = groupByValues.elementAt(groupIndex);
|
||||
|
||||
// Fetch the crop for the current group from groupedCrops
|
||||
String cropType = groupByValues.elementAt(groupIndex);
|
||||
String crop = groupedCrops[cropType]![rodIndex];
|
||||
double value = rod.toY;
|
||||
|
||||
String formattedValue;
|
||||
if (value >= 1000000) {
|
||||
formattedValue =
|
||||
(value / 1000000).toStringAsFixed(1) + 'M';
|
||||
} else if (value >= 1000) {
|
||||
formattedValue =
|
||||
(value / 1000).toStringAsFixed(1) + 'K';
|
||||
} else {
|
||||
formattedValue = value.toStringAsFixed(
|
||||
0); // for values smaller than 1000
|
||||
}
|
||||
|
||||
return BarTooltipItem(
|
||||
'$groupLabel\n$crop',
|
||||
const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: ' Value: $formattedValue',
|
||||
style: const TextStyle(
|
||||
color: Colors.yellow,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
touchCallback: (event, response) {
|
||||
if (event.isInterestedForInteractions &&
|
||||
response != null &&
|
||||
response.spot != null) {
|
||||
// setState(() {
|
||||
touchedGroupIndex = response.spot!.touchedBarGroupIndex;
|
||||
// });
|
||||
} else {
|
||||
// setState(() {
|
||||
touchedGroupIndex = -1; // Reset if no interaction
|
||||
// });
|
||||
}
|
||||
},
|
||||
),
|
||||
titlesData: FlTitlesData(
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
reservedSize: 20,
|
||||
interval: 100000,
|
||||
getTitlesWidget: (value, meta) {
|
||||
return Text(
|
||||
value.toInt().toString(),
|
||||
style: const TextStyle(fontSize: 12),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
reservedSize: 80, // Added space for rotated titles
|
||||
getTitlesWidget: (value, meta) {
|
||||
if (value < groupByValues.length) {
|
||||
String title = groupByValues.elementAt(value.toInt());
|
||||
return Transform.rotate(
|
||||
angle: -1.58, // Rotation in radians (~ -30 degrees)
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 80,
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
return null;
|
||||
},
|
||||
),
|
||||
touchCallback: (event, response) {
|
||||
if (event.isInterestedForInteractions &&
|
||||
response != null &&
|
||||
response.spot != null) {
|
||||
// setState(() {
|
||||
touchedGroupIndex = response.spot!.touchedBarGroupIndex;
|
||||
// });
|
||||
} else {
|
||||
// setState(() {
|
||||
touchedGroupIndex = -1; // Reset if no interaction
|
||||
// });
|
||||
}
|
||||
},
|
||||
),
|
||||
rightTitles:
|
||||
AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
topTitles:
|
||||
AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
),
|
||||
borderData: FlBorderData(
|
||||
show: true,
|
||||
border: const Border(
|
||||
// left: BorderSide(color: Colors.grey),
|
||||
bottom: BorderSide(color: Colors.white),
|
||||
titlesData: FlTitlesData(
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
reservedSize: 20,
|
||||
interval: 100000,
|
||||
getTitlesWidget: (value, meta) {
|
||||
return Text(
|
||||
value.toInt().toString(),
|
||||
style: const TextStyle(fontSize: 12),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
reservedSize: 80, // Added space for rotated titles
|
||||
getTitlesWidget: (value, meta) {
|
||||
if (value < groupByValues.length) {
|
||||
String title = groupByValues.elementAt(value.toInt());
|
||||
return Transform.rotate(
|
||||
angle: -1.58, // Rotation in radians (~ -30 degrees)
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 80,
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
),
|
||||
rightTitles:
|
||||
AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
topTitles:
|
||||
AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
),
|
||||
borderData: FlBorderData(
|
||||
show: true,
|
||||
border: const Border(
|
||||
// left: BorderSide(color: Colors.grey),
|
||||
bottom: BorderSide(color: Colors.white),
|
||||
),
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: false,
|
||||
drawVerticalLine: true,
|
||||
verticalInterval: 1,
|
||||
horizontalInterval: 100000,
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
getDrawingVerticalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
),
|
||||
barGroups:
|
||||
_buildHorizontalRotateBarGroups(chartData, groupByValues),
|
||||
alignment: BarChartAlignment.spaceAround,
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: false,
|
||||
drawVerticalLine: true,
|
||||
verticalInterval: 1,
|
||||
horizontalInterval: 100000,
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
getDrawingVerticalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
),
|
||||
barGroups:
|
||||
_buildHorizontalRotateBarGroups(chartData, groupByValues),
|
||||
alignment: BarChartAlignment.spaceAround,
|
||||
),
|
||||
))
|
||||
)
|
||||
// Expanded(
|
||||
// child: Stack(
|
||||
// children:[
|
||||
// BarChart(
|
||||
// BarChartData(
|
||||
// maxY: 400000,
|
||||
// rotationQuarterTurns: rotationTurns,
|
||||
// barTouchData: BarTouchData(
|
||||
// touchTooltipData: BarTouchTooltipData(
|
||||
// tooltipHorizontalAlignment: FLHorizontalAlignment.center,
|
||||
// // Only show tooltip when touched
|
||||
// getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
// if (rod.toY == 0 || touchedGroupIndex == -1) {
|
||||
// return null; // Don't show the tooltip if the value is 0 or there's no touch
|
||||
// }
|
||||
//
|
||||
// if (groupIndex == touchedGroupIndex) {
|
||||
// // print('Group Index: $groupIndex, Group : $group');
|
||||
//
|
||||
// // Get the group label dynamically
|
||||
// String groupLabel = groupByValues.elementAt(groupIndex);
|
||||
//
|
||||
// // Fetch the crop for the current group from groupedCrops
|
||||
// String cropType = groupByValues.elementAt(groupIndex);
|
||||
// String crop = groupedCrops[cropType]![rodIndex];
|
||||
// double value = rod.toY;
|
||||
//
|
||||
// String formattedValue;
|
||||
// if (value >= 1000000) {
|
||||
// formattedValue =
|
||||
// (value / 1000000).toStringAsFixed(1) + 'M';
|
||||
// } else if (value >= 1000) {
|
||||
// formattedValue =
|
||||
// (value / 1000).toStringAsFixed(1) + 'K';
|
||||
// } else {
|
||||
// formattedValue = value
|
||||
// .toStringAsFixed(0); // for values smaller than 1000
|
||||
// }
|
||||
//
|
||||
// return BarTooltipItem(
|
||||
// '$groupLabel\n$crop',
|
||||
// const TextStyle(
|
||||
// color: Colors.white,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// children: [
|
||||
// TextSpan(
|
||||
// text: ' Value: $formattedValue',
|
||||
// style: const TextStyle(
|
||||
// color: Colors.yellow,
|
||||
// fontWeight: FontWeight.w500,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
// return null;
|
||||
// },
|
||||
// ),
|
||||
// touchCallback: (event, response) {
|
||||
// if (event.isInterestedForInteractions &&
|
||||
// response != null &&
|
||||
// response.spot != null) {
|
||||
// // setState(() {
|
||||
// touchedGroupIndex = response.spot!.touchedBarGroupIndex;
|
||||
// // });
|
||||
// } else {
|
||||
// // setState(() {
|
||||
// touchedGroupIndex = -1; // Reset if no interaction
|
||||
// // });
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// titlesData: FlTitlesData(
|
||||
// leftTitles: AxisTitles(
|
||||
// sideTitles: SideTitles(
|
||||
// showTitles: false,
|
||||
// reservedSize: 20,
|
||||
// interval: 100000,
|
||||
// getTitlesWidget: (value, meta) {
|
||||
// return Text(
|
||||
// value.toInt().toString(),
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// bottomTitles: AxisTitles(
|
||||
// sideTitles: SideTitles(
|
||||
// showTitles: true,
|
||||
// reservedSize: 80, // Added space for rotated titles
|
||||
// getTitlesWidget: (value, meta) {
|
||||
// if (value < groupByValues.length) {
|
||||
// String title = groupByValues.elementAt(value.toInt());
|
||||
// return Transform.rotate(
|
||||
// angle: -1.58, // Rotation in radians (~ -30 degrees)
|
||||
// child: Center(
|
||||
// child: SizedBox(
|
||||
// width: 80,
|
||||
// child: Text(
|
||||
// title,
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// softWrap: true,
|
||||
// maxLines: 2,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// return const SizedBox.shrink();
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// rightTitles:
|
||||
// AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
// topTitles:
|
||||
// AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
// ),
|
||||
// borderData: FlBorderData(
|
||||
// show: true,
|
||||
// border: const Border(
|
||||
// // left: BorderSide(color: Colors.grey),
|
||||
// bottom: BorderSide(color: Colors.white),
|
||||
// ),
|
||||
// ),
|
||||
// gridData: FlGridData(
|
||||
// show: false,
|
||||
// drawVerticalLine: true,
|
||||
// verticalInterval: 1,
|
||||
// horizontalInterval: 100000,
|
||||
// getDrawingHorizontalLine: (value) {
|
||||
// return FlLine(
|
||||
// color: Colors.grey.withOpacity(0.5),
|
||||
// strokeWidth: 1,
|
||||
// );
|
||||
// },
|
||||
// getDrawingVerticalLine: (value) {
|
||||
// return FlLine(
|
||||
// color: Colors.grey.withOpacity(0.5),
|
||||
// strokeWidth: 1,
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// barGroups:
|
||||
// _buildHorizontalRotateBarGroups(chartData, groupByValues),
|
||||
// alignment: BarChartAlignment.spaceAround,
|
||||
// ),
|
||||
//
|
||||
// ),
|
||||
// // Overlay Texts
|
||||
// ..._buildHorizontalRotateBarGroups(chartData, groupByValues)
|
||||
// .asMap()
|
||||
// .entries
|
||||
// .expand((entry) {
|
||||
// int groupIndex = entry.key;
|
||||
// BarChartGroupData groupData = entry.value;
|
||||
// return groupData.barRods.asMap().entries.map((rodEntry) {
|
||||
// int rodIndex = rodEntry.key;
|
||||
// BarChartRodData rodData = rodEntry.value;
|
||||
//
|
||||
// // Position calculation
|
||||
// double barHeight = rodData.toY / 400000 * MediaQuery.of(context).size.height;
|
||||
//
|
||||
// return Positioned(
|
||||
// left: (groupIndex * 80).toDouble() + 20, // Adjust based on spacing
|
||||
// bottom: barHeight / 2, // Centered inside the bar
|
||||
// child: Transform.rotate(
|
||||
// angle: -0.1,
|
||||
// child: Text(
|
||||
// // '${rodData.toY.toInt()}',
|
||||
// "123",
|
||||
// style: TextStyle(
|
||||
// color: Colors.black,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 12,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }).toList();
|
||||
// }).toList(),
|
||||
// ]))
|
||||
]);
|
||||
|
||||
default:
|
||||
return Center(child: Text('Unknown chart type'));
|
||||
}
|
||||
@ -1778,12 +1999,11 @@ class ChartWidget extends StatelessWidget {
|
||||
toY: value, // Use the parsed value
|
||||
color: barColor, // Dynamic color
|
||||
width: 20,
|
||||
// backDrawRodData: BackgroundBarChartRodData(
|
||||
// backDrawRodData: BackgroundBarChartRodData(
|
||||
// show: true,
|
||||
// toY: 400000,
|
||||
// color: Colors.grey.shade300,
|
||||
// ),
|
||||
//
|
||||
);
|
||||
}).toList();
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:external_repos/external_repos.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@ -17,7 +18,7 @@ import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
|
||||
import 'package:uae_stat/presentation/components/space.dart';
|
||||
import 'package:uae_stat/presentation/components/themed_text_field.dart';
|
||||
import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../../Screens/auth_verification/registration.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
|
||||
@ -27,7 +28,9 @@ import '../../components/my_toggle.dart';
|
||||
class LoginRoute extends HookConsumerWidget {
|
||||
final pb = PocketBase('https://pb.venbait.in');
|
||||
// final _pb = PocketBase('http://127.0.0.1:8090');
|
||||
LoginRoute({super.key});
|
||||
final bool isLoginScreen; // Pass `true` if this is the login screen
|
||||
LoginRoute({Key? key, required this.isLoginScreen}) : super(key: key);
|
||||
// LoginRoute({super.key});
|
||||
dynamic userData;
|
||||
String? role;
|
||||
|
||||
@ -253,6 +256,22 @@ class LoginRoute extends HookConsumerWidget {
|
||||
if (!context.mounted || session == null) return;
|
||||
final userId = session.id;
|
||||
if (userId.isNotEmpty) {
|
||||
final url =
|
||||
Uri.parse("https://pb.venbait.in/api/login_success?id=$userId");
|
||||
|
||||
try {
|
||||
final response = await http.get(url);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print("Login success API call successful: ${response.body}");
|
||||
} else {
|
||||
print(
|
||||
"Failed to call login success API. Status code: ${response.statusCode}");
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error calling login success API: $e");
|
||||
}
|
||||
|
||||
await saveUserId(userId);
|
||||
}
|
||||
try {
|
||||
@ -340,7 +359,10 @@ class LoginRoute extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
6.horizontalSpace,
|
||||
const Icon(Icons.chevron_right_outlined),
|
||||
const Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: Colors.white, // Set your desired color here
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -368,8 +390,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
validator: (text) {
|
||||
if (text == null || text.isEmpty) {
|
||||
return context.translate('Required', 'مطلوب');
|
||||
}
|
||||
else if (text.length < 8) {
|
||||
} else if (text.length < 8) {
|
||||
return 'The password must be at least 8 characters';
|
||||
}
|
||||
return FieldValidator.password(minLength: 8)(text);
|
||||
@ -411,7 +432,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
10.verticalSpace,
|
||||
Text(
|
||||
context.translate(
|
||||
'Please login to access UAE’s key official statistics',
|
||||
'Please login to access \n UAE’s key official statistics',
|
||||
'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة',
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
@ -422,7 +443,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
),
|
||||
fontSize: 18,
|
||||
color: const Color(0xff898C81),
|
||||
fontWeight: FontWeight.w700,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -466,61 +487,61 @@ class LoginRoute extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
);
|
||||
final continueAsGuestBtn = SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
prefs.clear();
|
||||
final userId = 'guest';
|
||||
if (userId.isNotEmpty) {
|
||||
await saveUserId(userId);
|
||||
}
|
||||
context.go('/myhomepage');
|
||||
//context.go('/${context.language}/${BottomNavBarItem.home.routePath}'),
|
||||
},
|
||||
//context.go('/${context.language}/${BottomNavBarItem.home.routePath}'),
|
||||
style: ButtonStyle(
|
||||
shape: WidgetStatePropertyAll(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
padding: const WidgetStatePropertyAll(
|
||||
EdgeInsets.symmetric(vertical: 10.5),
|
||||
),
|
||||
textStyle: WidgetStatePropertyAll(
|
||||
TextStyle(
|
||||
fontFamily: context.translate(
|
||||
'Roboto',
|
||||
'NotoKufi',
|
||||
),
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
MyTheme.topicColor(IndicatorTopic.environment),
|
||||
),
|
||||
foregroundColor: const WidgetStatePropertyAll(
|
||||
Colors.white,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(
|
||||
'Continue as Guest',
|
||||
'استمر كضيف',
|
||||
),
|
||||
),
|
||||
6.horizontalSpace,
|
||||
const Icon(Icons.chevron_right_outlined),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
// final continueAsGuestBtn = SizedBox(
|
||||
// width: double.infinity,
|
||||
// child: ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// prefs.clear();
|
||||
// final userId = 'guest';
|
||||
// if (userId.isNotEmpty) {
|
||||
// await saveUserId(userId);
|
||||
// }
|
||||
// context.go('/myhomepage');
|
||||
// //context.go('/${context.language}/${BottomNavBarItem.home.routePath}'),
|
||||
// },
|
||||
// //context.go('/${context.language}/${BottomNavBarItem.home.routePath}'),
|
||||
// style: ButtonStyle(
|
||||
// shape: WidgetStatePropertyAll(
|
||||
// RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(10),
|
||||
// ),
|
||||
// ),
|
||||
// padding: const WidgetStatePropertyAll(
|
||||
// EdgeInsets.symmetric(vertical: 10.5),
|
||||
// ),
|
||||
// textStyle: WidgetStatePropertyAll(
|
||||
// TextStyle(
|
||||
// fontFamily: context.translate(
|
||||
// 'Roboto',
|
||||
// 'NotoKufi',
|
||||
// ),
|
||||
// fontSize: 16,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// backgroundColor: WidgetStatePropertyAll(
|
||||
// MyTheme.topicColor(IndicatorTopic.environment),
|
||||
// ),
|
||||
// foregroundColor: const WidgetStatePropertyAll(
|
||||
// Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// Text(
|
||||
// context.translate(
|
||||
// 'Continue as Guest',
|
||||
// 'استمر كضيف',
|
||||
// ),
|
||||
// ),
|
||||
// 6.horizontalSpace,
|
||||
// const Icon(Icons.chevron_right_outlined),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
final fcscBanner = Image.asset(
|
||||
BannerAssetPath.fcsc,
|
||||
height: 40,
|
||||
@ -554,15 +575,46 @@ class LoginRoute extends HookConsumerWidget {
|
||||
20.verticalSpace,
|
||||
dontHaveAnAccountRegisterBtn,
|
||||
20.verticalSpace,
|
||||
continueAsGuestBtn,
|
||||
// continueAsGuestBtn,
|
||||
25.verticalSpace,
|
||||
fcscBanner,
|
||||
],
|
||||
);
|
||||
final bgScaffold = Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: SafeArea(child: scaffoldBody),
|
||||
// final bgScaffold = Scaffold(
|
||||
// backgroundColor: Colors.white,
|
||||
// body: SafeArea(child: scaffoldBody),
|
||||
// );
|
||||
// return bgScaffold;
|
||||
return PopScope(
|
||||
canPop: !isLoginScreen, // Allow back navigation only if not login screen
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (didPop) return;
|
||||
_showExitConfirmation(context); // Show exit confirmation dialog
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: SafeArea(child: scaffoldBody),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showExitConfirmation(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text("Exit App"),
|
||||
content: Text("Are you sure you want to exit?"),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(), // Close dialog
|
||||
child: Text("Cancel"),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => SystemNavigator.pop(), // Exit the app
|
||||
child: Text("Exit"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
return bgScaffold;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,6 +165,8 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
||||
import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart';
|
||||
@ -205,7 +207,7 @@ class EconomyStatsWidget extends ConsumerStatefulWidget {
|
||||
|
||||
class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
List<dynamic> data = [];
|
||||
|
||||
final _pb = PocketBase('https://pb.venbait.in');
|
||||
bool isLoading = true;
|
||||
|
||||
final GlobalKey cardTopicKey = GlobalKey();
|
||||
@ -213,11 +215,12 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
late TutorialCoachMark tutorialCoachMark;
|
||||
late List<TargetFocus> homeTargets;
|
||||
late List<TargetFocus> previousHomeTargets;
|
||||
Offset _imageCardPosition =Offset.zero;
|
||||
Offset _imageTopicPosition =Offset.zero;
|
||||
Offset _imageCardPosition = Offset.zero;
|
||||
Offset _imageTopicPosition = Offset.zero;
|
||||
|
||||
void _calculateCardPosition() {
|
||||
final RenderBox cardRenderBox = cardsKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final RenderBox cardRenderBox =
|
||||
cardsKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final Offset cardPosition = cardRenderBox.localToGlobal(Offset.zero);
|
||||
final Size cardSize = cardRenderBox.size;
|
||||
|
||||
@ -233,10 +236,10 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
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(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;
|
||||
}
|
||||
@ -288,11 +291,10 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
},
|
||||
)..show(context: context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _initTarget(){
|
||||
homeTargets=[
|
||||
void _initTarget() {
|
||||
homeTargets = [
|
||||
TargetFocus(
|
||||
identify: 'cardTopicKey',
|
||||
keyTarget: cardTopicKey,
|
||||
@ -308,7 +310,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
align: ContentAlign.bottom,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height*0.69,
|
||||
height: MediaQuery.of(context).size.height * 0.69,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
@ -353,12 +355,14 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xFF7DAFBC),
|
||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1),
|
||||
border: Border.all(
|
||||
color: Color(0xFF7DAFBC), width: 1),
|
||||
),
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
iconSize: 20,
|
||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
||||
icon: const Icon(Icons.arrow_forward,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.next();
|
||||
},
|
||||
@ -379,21 +383,18 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
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,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -404,17 +405,17 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text:AppLocalizations.of(context)!.economy,
|
||||
text: AppLocalizations.of(context)!.economy,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 0,
|
||||
space: 40,),
|
||||
|
||||
space: 40,
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child:
|
||||
SizedBox(
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height *0.5, // Set an appropriate height for the Stack
|
||||
height: MediaQuery.of(context).size.height *
|
||||
0.5, // Set an appropriate height for the Stack
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
@ -425,7 +426,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () =>handleSkip,
|
||||
onPressed: () => handleSkip,
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@ -457,11 +458,13 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(color: Colors.white, width: 2.0),
|
||||
border: Border.all(
|
||||
color: Colors.white, width: 2.0),
|
||||
),
|
||||
child: IconButton(
|
||||
iconSize: 20,
|
||||
icon: const Icon(Icons.arrow_back, color: Colors.white),
|
||||
icon: const Icon(Icons.arrow_back,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.previous();
|
||||
},
|
||||
@ -472,11 +475,13 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xFF7DAFBC),
|
||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1),
|
||||
border: Border.all(
|
||||
color: Color(0xFF7DAFBC), width: 1),
|
||||
),
|
||||
child: IconButton(
|
||||
iconSize: 20,
|
||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
||||
icon: const Icon(Icons.arrow_forward,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.next();
|
||||
},
|
||||
@ -496,22 +501,19 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
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,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -519,24 +521,25 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
];
|
||||
}
|
||||
|
||||
void _initPreviousTarget(){
|
||||
previousHomeTargets=[
|
||||
void _initPreviousTarget() {
|
||||
previousHomeTargets = [
|
||||
TargetFocus(
|
||||
identify: 'cardsKey',
|
||||
keyTarget: cardsKey,
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text:AppLocalizations.of(context)!.economy,
|
||||
text: AppLocalizations.of(context)!.economy,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 0,
|
||||
space: 40,),
|
||||
space: 40,
|
||||
),
|
||||
TargetContent(
|
||||
align: ContentAlign.bottom,
|
||||
child:
|
||||
SizedBox(
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height *0.5, // Set an appropriate height for the Stack
|
||||
height: MediaQuery.of(context).size.height *
|
||||
0.5, // Set an appropriate height for the Stack
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
@ -547,7 +550,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () =>handleSkip(),
|
||||
onPressed: () => handleSkip(),
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@ -579,10 +582,12 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(color: Colors.white, width: 2.0),
|
||||
border: Border.all(
|
||||
color: Colors.white, width: 2.0),
|
||||
),
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Colors.white),
|
||||
icon: const Icon(Icons.arrow_back,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.next();
|
||||
},
|
||||
@ -593,14 +598,21 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xFF7DAFBC),
|
||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1.5),
|
||||
border: Border.all(
|
||||
color: Color(0xFF7DAFBC), width: 1.5),
|
||||
),
|
||||
child: IconButton(
|
||||
iconSize: 20,
|
||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
||||
icon: const Icon(Icons.arrow_forward,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
ref.read(previousHomeTourProvider.notifier).state=true;
|
||||
ref.read(chartsTourProvider.notifier).state=false;
|
||||
ref
|
||||
.read(
|
||||
previousHomeTourProvider.notifier)
|
||||
.state = true;
|
||||
ref
|
||||
.read(chartsTourProvider.notifier)
|
||||
.state = false;
|
||||
tutorialCoachMark.finish();
|
||||
},
|
||||
),
|
||||
@ -620,21 +632,18 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
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,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -645,7 +654,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
shape: ShapeLightFocus.RRect,
|
||||
contents: [
|
||||
createTargetContent(
|
||||
text:AppLocalizations.of(context)!.home_topic,
|
||||
text: AppLocalizations.of(context)!.home_topic,
|
||||
alignment: ContentAlign.bottom,
|
||||
gap: 45,
|
||||
space: 40,
|
||||
@ -654,7 +663,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
align: ContentAlign.bottom,
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height*0.69,
|
||||
height: MediaQuery.of(context).size.height * 0.69,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
@ -702,11 +711,13 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xFF7DAFBC),
|
||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1.5),
|
||||
border: Border.all(
|
||||
color: Color(0xFF7DAFBC), width: 1.5),
|
||||
),
|
||||
child: IconButton(
|
||||
iconSize: 20,
|
||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
||||
icon: const Icon(Icons.arrow_forward,
|
||||
color: Colors.white),
|
||||
onPressed: () {
|
||||
tutorialCoachMark.previous();
|
||||
},
|
||||
@ -727,21 +738,18 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
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,
|
||||
),
|
||||
),
|
||||
]
|
||||
),
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -749,15 +757,12 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final locale = ref.read(localeProvider);
|
||||
fetchData(locale?.languageCode ?? 'en');
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_starTourRender();
|
||||
});
|
||||
_fetchUserData();
|
||||
}
|
||||
|
||||
// @override
|
||||
@ -768,6 +773,37 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
// fetchData(locale); // Pass the locale to the fetchData method
|
||||
// }
|
||||
|
||||
Future<String?> getUserId() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString('userId'); // Retrieve the userId
|
||||
}
|
||||
|
||||
Future<void> _fetchUserData() async {
|
||||
try {
|
||||
final userId = await getUserId();
|
||||
print('EDIT PROFILE isPageLoad');
|
||||
final adminAuth = await _pb.admins
|
||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||
final adminToken = adminAuth.token;
|
||||
print('adminToken- $adminToken');
|
||||
final userDetailsResponse = await _pb.collection('users').getOne(
|
||||
userId!,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $adminToken',
|
||||
},
|
||||
);
|
||||
final loginCount = userDetailsResponse.data['login_count'];
|
||||
print(loginCount);
|
||||
if (loginCount == 1) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_starTourRender();
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching user details: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchData(locale) async {
|
||||
const baseUrl = 'https://pb.venbait.in/api/getHomePageData';
|
||||
try {
|
||||
@ -875,7 +911,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
RoundedCornerContainer(
|
||||
key: mainTopic['main_topic'] =='ECONOMY'
|
||||
key: mainTopic['main_topic'] == 'ECONOMY'
|
||||
? cardTopicKey
|
||||
: null,
|
||||
text: mainTopic['main_topic'],
|
||||
@ -889,7 +925,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
SizedBox(
|
||||
height: myheight / 4.8, // Set dynamic height
|
||||
child: Container(
|
||||
key:mainTopic['main_topic'] == 'ECONOMY'
|
||||
key: mainTopic['main_topic'] == 'ECONOMY'
|
||||
? cardsKey
|
||||
: null,
|
||||
// color: Colors.grey[200], // Set a background color for the scrollable container
|
||||
@ -1111,7 +1147,6 @@ class InfoCard extends StatelessWidget {
|
||||
final encodedTitle = Uri.encodeComponent(title);
|
||||
final encodedKey = Uri.encodeQueryComponent('home');
|
||||
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context.go(
|
||||
|
||||
@ -2,7 +2,7 @@ name: uae_stat
|
||||
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
|
||||
publish_to: "none"
|
||||
#version: 0.5.10
|
||||
version: 1.0.5+6
|
||||
version: 1.0.6+7
|
||||
|
||||
environment:
|
||||
sdk: ">=3.2.3 <4.0.0"
|
||||
@ -117,6 +117,9 @@ flutter:
|
||||
- assets/app_tour/
|
||||
- assets/icons/uae_numbers/bookmarks.png
|
||||
- assets/icons/uae_numbers/share.png
|
||||
- assets/icons/misc/vector.png
|
||||
- assets/icons/misc/visible_on.png
|
||||
- assets/icons/misc/visibility_off.png
|
||||
|
||||
fonts:
|
||||
- family: Segoe
|
||||
|
||||
Loading…
Reference in New Issue
Block a user