notification and no internet added

This commit is contained in:
venbaittech 2025-03-12 17:29:35 +05:30
parent 3a799623d5
commit ef761a8d0a
20 changed files with 524 additions and 317 deletions

View File

@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) {
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
flutterVersionCode = "34"
flutterVersionCode = "36"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
flutterVersionName = "1.0.33"
flutterVersionName = "1.0.35"
}
def keystorePropertiesFile = rootProject.file("key.properties")

View File

@ -176,7 +176,7 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
// If no internet, redirect to InternetCheckScreen
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.go('/internetcheck');
context.push('/internetcheck');
}
});

View File

@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/my_router.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
@ -21,7 +22,11 @@ class CreateNewPw extends ConsumerStatefulWidget {
final String email;
final String? keyParam;
const CreateNewPw({Key? key, required this.userId, required this.email, required this.keyParam});
const CreateNewPw(
{Key? key,
required this.userId,
required this.email,
required this.keyParam});
@override
ConsumerState<CreateNewPw> createState() => _CreateNewPwState();
@ -80,21 +85,22 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
List<String> missingConstraints = [];
if (!hasUppercase.hasMatch(value)) {
missingConstraints.add(context.translate('uppercase letter','حرف كبير'));
missingConstraints.add(context.translate('uppercase letter', 'حرف كبير'));
}
if (!hasLowercase.hasMatch(value)) {
missingConstraints.add(context.translate('lowercase letter','حرف صغير'));
missingConstraints.add(context.translate('lowercase letter', 'حرف صغير'));
}
if (!hasDigit.hasMatch(value)) {
missingConstraints.add(context.translate('numeric digit','رقم'));
missingConstraints.add(context.translate('numeric digit', 'رقم'));
}
if (!hasSpecialCharacter.hasMatch(value)) {
missingConstraints.add(context.translate('special character','رمز خاص'));
missingConstraints.add(context.translate('special character', 'رمز خاص'));
}
// If there are missing constraints, return a consolidated message
if (missingConstraints.isNotEmpty) {
return context.translate('At least one ${missingConstraints.join(', ')}','${missingConstraints.join(', ')}على الأقل واحد ');
return context.translate('At least one ${missingConstraints.join(', ')}',
'${missingConstraints.join(', ')}على الأقل واحد ');
}
_newPassword = value; // Store for validation
@ -160,7 +166,8 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(context)!.password_update_successfully),
content: Text(
AppLocalizations.of(context)!.password_update_successfully),
backgroundColor: Colors.green,
),
);
@ -180,7 +187,8 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(context)!.your_old_password_incorrect),
content:
Text(AppLocalizations.of(context)!.your_old_password_incorrect),
backgroundColor: Colors.red,
),
);
@ -201,19 +209,26 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: SafeArea(
child: _isPasswordUpdated
? _buildSuccessContent(screenHeight, screenWidth)
: _buildPasswordForm(ref,screenHeight, screenWidth),
: _buildPasswordForm(ref, screenHeight, screenWidth),
),
),
);
}
Widget _buildPasswordForm(WidgetRef ref ,double screenHeight, double screenWidth) {
Widget _buildPasswordForm(
WidgetRef ref, double screenHeight, double screenWidth) {
final passwordLocale = ref.watch(localeProvider);
return Form(
key: _formKey,
@ -221,7 +236,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
padding: const EdgeInsets.all(24.0),
child: Column(
children: [
// SizedBox(height: screenHeight / 7),
// SizedBox(height: screenHeight / 7),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -230,7 +245,11 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
context.pop();
},
child: Container(
margin: EdgeInsets.only(top: 10,left: 1,bottom: 16,right: 1), // Add margin for positioning
margin: EdgeInsets.only(
top: 10,
left: 1,
bottom: 16,
right: 1), // Add margin for positioning
child: Icon(
// Icons.close,
Icons.arrow_back_ios,
@ -261,45 +280,48 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
},
);
},
),// Right icon
), // Right icon
],
),
SizedBox(height: screenHeight / 30),
Text(
// "Create New Password",
AppLocalizations.of(context)!.create_new_password,
style: TextStyle(
fontSize: passwordLocale?.languageCode ==
'ar'
? 24
:26,
fontSize: passwordLocale?.languageCode == 'ar' ? 24 : 26,
fontWeight: FontWeight.w300,
),
),
SizedBox(height: 10),
Text.rich(
TextSpan(
children: [
Text.rich(
TextSpan(
text: context.translate('Your New Password Must Be Different\n','يجب أن تكون كلمة المرور الجديدة مختلفة\n',),
style: TextStyle(fontSize: passwordLocale?.languageCode ==
'ar'
? 14
:15,fontWeight: FontWeight.w700, color: Color(0xFF898C81)),
children: [
TextSpan(
text: context.translate(
'Your New Password Must Be Different\n',
'يجب أن تكون كلمة المرور الجديدة مختلفة\n',
),
style: TextStyle(
fontSize:
passwordLocale?.languageCode == 'ar' ? 14 : 15,
fontWeight: FontWeight.w700,
color: Color(0xFF898C81)),
),
TextSpan(
text: context.translate('from Previously Used Password',
'عن كلمة المرور المستخدمة سابقًا'),
style: TextStyle(
fontSize:
passwordLocale?.languageCode == 'ar' ? 14 : 15,
color: Color(0xFF898C81),
fontWeight: FontWeight.w700),
),
],
),
TextSpan(
text: context.translate('from Previously Used Password','عن كلمة المرور المستخدمة سابقًا'),
style: TextStyle(fontSize: passwordLocale?.languageCode ==
'ar'
? 14
:15, color: Color(0xFF898C81), fontWeight: FontWeight.w700),
),
],
),
textAlign: TextAlign.center,
),
textAlign: TextAlign.center,
),
SizedBox(height: 20),
TextFormField(
obscureText: _obscureOldPassword,
@ -309,29 +331,25 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
// prefixIcon: Icon(Icons.lock, color: Colors.blue),
hintStyle: TextStyle(
color: Color(0xFFC3C6CB),
fontWeight: FontWeight.w400,
fontFamily: 'Roboto'
),
prefixIconConstraints:
const BoxConstraints(
fontWeight: FontWeight.w400,
fontFamily: 'Roboto'),
prefixIconConstraints: const BoxConstraints(
maxWidth: 25 + 16 + 10,
maxHeight: 25 + (8 * 2),
),
prefixIcon: Padding(
padding: const EdgeInsetsDirectional
.only(
padding: const EdgeInsetsDirectional.only(
start: 16,
end: 10,
),
child: Image.asset(
MiscIconAssetPath.lock,
fit: BoxFit.fitHeight,
height: 25,
width: 25,
color: MyTheme.topicColor(
IndicatorTopic.economy)
.shade300,
),),
child: Image.asset(
MiscIconAssetPath.lock,
fit: BoxFit.fitHeight,
height: 25,
width: 25,
color: MyTheme.topicColor(IndicatorTopic.economy).shade300,
),
),
suffixIcon: IconButton(
// icon: Icon(
// _obscureOldPassword
@ -342,17 +360,16 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
icon: Image.asset(
_obscureOldPassword
? MiscIconAssetPath
.visibilityOff
? MiscIconAssetPath.visibilityOff
: MiscIconAssetPath.visibleOn,
color: Color(
0xFF9EA2A9,), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
0xFF9EA2A9,
), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
width: 24,
height: 24,
),
onPressed: () {
setState(() {
_obscureOldPassword = !_obscureOldPassword;
@ -360,36 +377,27 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
},
),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: MyTheme.topicColor(
IndicatorTopic.economy)
.shade400,
color:
MyTheme.topicColor(IndicatorTopic.economy).shade400,
width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.deepPurple,
width: 2), // Focused border
color: Colors.deepPurple, width: 2), // Focused border
),
errorBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Color(0xFFb22222),
width: 1), // Error border
color: Color(0xFFb22222), width: 1), // Error border
),
focusedErrorBorder:
OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Color(0xFFb22222),
width:
1), // Match the error color
width: 1), // Match the error color
),
),
validator: _validateOldPassword,
@ -405,28 +413,23 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
hintStyle: TextStyle(
color: Color(0xFFC3C6CB),
fontWeight: FontWeight.w400,
fontFamily: 'Roboto'
),
prefixIconConstraints:
const BoxConstraints(
fontFamily: 'Roboto'),
prefixIconConstraints: const BoxConstraints(
maxWidth: 25 + 16 + 10,
maxHeight: 25 + (8 * 2),
),
prefixIcon: Padding(
padding: const EdgeInsetsDirectional
.only(
padding: const EdgeInsetsDirectional.only(
start: 16,
end: 10,
),
child: Image.asset(
MiscIconAssetPath.lock,
fit: BoxFit.fitHeight,
height: 25,
width: 25,
color: MyTheme.topicColor(
IndicatorTopic.economy)
.shade300,
),
child: Image.asset(
MiscIconAssetPath.lock,
fit: BoxFit.fitHeight,
height: 25,
width: 25,
color: MyTheme.topicColor(IndicatorTopic.economy).shade300,
),
),
suffixIcon: IconButton(
@ -439,8 +442,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
icon: Image.asset(
_obscureNewPassword
? MiscIconAssetPath
.visibilityOff
? MiscIconAssetPath.visibilityOff
: MiscIconAssetPath.visibleOn,
color: Color(
@ -449,7 +451,6 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
height: 24,
),
onPressed: () {
setState(() {
_obscureNewPassword = !_obscureNewPassword;
@ -457,36 +458,27 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
},
),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: MyTheme.topicColor(
IndicatorTopic.economy)
.shade400,
color:
MyTheme.topicColor(IndicatorTopic.economy).shade400,
width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.deepPurple,
width: 2), // Focused border
color: Colors.deepPurple, width: 2), // Focused border
),
errorBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Color(0xFFb22222),
width: 1), // Error border
color: Color(0xFFb22222), width: 1), // Error border
),
focusedErrorBorder:
OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Color(0xFFb22222),
width:
1), // Match the error color
width: 1), // Match the error color
),
),
validator: _validateNewPassword,
@ -500,28 +492,23 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
hintStyle: TextStyle(
color: Color(0xFFC3C6CB),
fontWeight: FontWeight.w400,
fontFamily: 'Roboto'
),
prefixIconConstraints:
const BoxConstraints(
fontFamily: 'Roboto'),
prefixIconConstraints: const BoxConstraints(
maxWidth: 25 + 16 + 10,
maxHeight: 25 + (8 * 2),
),
prefixIcon: Padding(
padding: const EdgeInsetsDirectional
.only(
padding: const EdgeInsetsDirectional.only(
start: 16,
end: 10,
),
child: Image.asset(
MiscIconAssetPath.lock,
fit: BoxFit.fitHeight,
height: 25,
width: 25,
color: MyTheme.topicColor(
IndicatorTopic.economy)
.shade300,
),
MiscIconAssetPath.lock,
fit: BoxFit.fitHeight,
height: 25,
width: 25,
color: MyTheme.topicColor(IndicatorTopic.economy).shade300,
),
),
suffixIcon: IconButton(
@ -532,10 +519,9 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
// color: Colors.blue,
// ),
icon: Image.asset(
_obscureConfirmPassword
? MiscIconAssetPath
.visibilityOff
icon: Image.asset(
_obscureConfirmPassword
? MiscIconAssetPath.visibilityOff
: MiscIconAssetPath.visibleOn,
color: Color(
@ -551,36 +537,27 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
),
// border: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: MyTheme.topicColor(
IndicatorTopic.economy)
.shade400,
color:
MyTheme.topicColor(IndicatorTopic.economy).shade400,
width: 1),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.deepPurple,
width: 2), // Focused border
color: Colors.deepPurple, width: 2), // Focused border
),
errorBorder: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Color(0xFFb22222),
width: 1), // Error border
color: Color(0xFFb22222), width: 1), // Error border
),
focusedErrorBorder:
OutlineInputBorder(
borderRadius:
BorderRadius.circular(10),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Color(0xFFb22222),
width:
1), // Match the error color
width: 1), // Match the error color
),
),
validator: _validateConfirmPassword,
@ -591,7 +568,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
child: ElevatedButton(
onPressed: () async {
setState(() {
hasValidated=true;
hasValidated = true;
});
if ((_formKey.currentState?.validate() ?? false)) {
await updatePassword(
@ -612,11 +589,11 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context)!.save,
style: TextStyle(fontSize: passwordLocale?.languageCode ==
'ar'
? 14
:18, color: Colors.white),
AppLocalizations.of(context)!.save,
style: TextStyle(
fontSize:
passwordLocale?.languageCode == 'ar' ? 14 : 18,
color: Colors.white),
),
SizedBox(width: 2),
Icon(
@ -640,7 +617,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
// ),
// ),
// ),
child: fcscBanner,
child: fcscBanner,
),
],
),
@ -710,7 +687,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
'Login',
'تسجيل الدخول',
),
style: TextStyle(
style: TextStyle(
fontFamily: context.translate(
'Roboto',
'Roboto',
@ -720,7 +697,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
),
),
6.horizontalSpace,
const Icon(Icons.chevron_right_outlined,color:Colors.white),
const Icon(Icons.chevron_right_outlined, color: Colors.white),
],
),
),
@ -743,4 +720,4 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
),
);
}
}
}

View File

@ -6,6 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.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/banner_asset_path.dart';
@ -344,6 +345,12 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
double screenwidth = MediaQuery.of(context).size.width;
final registerLocale = ref.watch(localeProvider);
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
Widget buildIconContainer(IconData icon, Color iconColor) {
return Container(
width: 60,

View File

@ -2104,7 +2104,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
// If no internet, redirect to InternetCheckScreen
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.go('/internetcheck');
context.push('/internetcheck');
}
});

View File

@ -300,12 +300,19 @@ class ChartWidget extends StatelessWidget {
}).toList();
}
List<Widget> generateIndicators(dynamic chartData, String groupByValue) {
List<Widget> generateIndicators(dynamic chartData) {
var groupByKeyValue;
if (chartData['chart_type_json']['chart_type'] == 'bar_chart_horizontal' ||
chartData['chart_type_json']['chart_type'] == 'horizontal_rotate') {
groupByKeyValue = chartData['chart_type_json']['y_group'] ?? '';
} else {
groupByKeyValue = chartData['chart_type_json']['x_group'] ?? '';
}
return chartData['response'].asMap().entries.map<Widget>((entry) {
int index = entry.key;
var data = entry.value;
Color color = Colors.primaries[index % Colors.primaries.length];
String title = data['ObsKey'][groupByValue] ?? '';
String title = data['ObsKey'][groupByKeyValue] ?? '';
String shortTitle =
title.length > 10 ? '${title.substring(0, 10)}' : title;
@ -403,7 +410,6 @@ class ChartWidget extends StatelessWidget {
Widget buildChart(dynamic chartData, BuildContext context) {
// print('bodyColor- $bodyColor');
print('chartDataccccccc $chartData');
// Extract group_by dynamically from the chartData
if (chartData == null || chartData['response'] == null) {
return Center(child: Text('No chart data available'));
}
@ -420,7 +426,6 @@ class ChartWidget extends StatelessWidget {
groupByKey = chartData['chart_type_json']['x_group'] ?? '';
}
// String groupByKey = chartData['group_by'] ?? '';
print('groupByKey $groupByKey');
Set<String> groupByValues = extractGroupByValues(chartData, groupByKey);
print('groupByValues $groupByValues');
@ -590,16 +595,8 @@ class ChartWidget extends StatelessWidget {
child: Column(
// Change Row to Column
crossAxisAlignment: CrossAxisAlignment.start,
children:
generateIndicators(chartData, chartData['group_by']),
children: generateIndicators(chartData),
),
// child: Wrap(
// spacing: 2,
// runSpacing: 5,
// children:
// generateIndicators(chartData, chartData['group_by']),
// ),
),
),
),
@ -827,6 +824,15 @@ class ChartWidget extends StatelessWidget {
.map<int>((entry) =>
int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0)
.toList();
// Sort in ascending order
years.sort();
// Sort in descending order
// years.sort((a, b) => b.compareTo(a));
print(years);
print('years $years');
if (years.isEmpty) {
// Return an empty chart if no data
@ -850,7 +856,7 @@ class ChartWidget extends StatelessWidget {
int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
return year >= minYear && year <= maxYear;
}).toList();
print('LnTrnd2');
print('LnTrnd2 $filteredData');
// Set<double> uniqueXValues = filteredData
// .map<double>(
@ -2662,12 +2668,14 @@ class ChartWidget extends StatelessWidget {
// Use the timePeriod directly as a string for x-axis
double xValue = parseTimePeriod(timePeriod);
print('spotss');
print('spotss $xValue');
// double yValue = double.parse(entry['ObsValue']['Value']);
double yValue;
var value = entry['ObsValue']['Value'];
print('LineTrend $value');
if (value is int) {
yValue = value.toDouble();
} else if (value is double) {
@ -2678,9 +2686,11 @@ class ChartWidget extends StatelessWidget {
} else {
throw Exception("Unexpected value type: ${value.runtimeType}");
}
print('LineTrendX $xValue');
print('LineTrendY $yValue');
return FlSpot(xValue, yValue);
}).toList();
}).toList()
..sort((a, b) => a.x.compareTo(b.x));
print('spots - $spots');
@ -3257,6 +3267,15 @@ class ChartWidget extends StatelessWidget {
List<BarChartGroupData> _buildHorizontalRotateBarGroups(
dynamic chartData, Set<String> groupByValues) {
String groupByKeyValueData;
if (chartData['chart_type_json']['chart_type'] == 'bar_chart_horizontal' ||
chartData['chart_type_json']['chart_type'] == 'horizontal_rotate') {
groupByKeyValueData = chartData['chart_type_json']['y_group'] ?? '';
} else {
groupByKeyValueData = chartData['chart_type_json']['x_group'] ?? '';
}
List<dynamic> responseData = chartData['response'];
List<BarChartGroupData> barGroups = [];
int colorIndex = 0;
@ -3269,7 +3288,7 @@ class ChartWidget extends StatelessWidget {
// Filter data for the current group (grouping by CROP_TYPE)
List<dynamic> groupData = responseData.where((entry) {
return entry['ObsKey'][chartData['group_by']] == groupValue;
return entry['ObsKey'][groupByKeyValueData] == groupValue;
}).toList();
// Create BarChartRodData for each bar in the group
@ -3337,6 +3356,15 @@ class ChartWidget extends StatelessWidget {
dynamic chartData,
Set<String> groupByValues,
Map<String, Color> chartBarColors) {
String groupByKeyValueData1;
if (chartData['chart_type_json']['chart_type'] == 'bar_chart_horizontal' ||
chartData['chart_type_json']['chart_type'] == 'horizontal_rotate') {
groupByKeyValueData1 = chartData['chart_type_json']['y_group'] ?? '';
} else {
groupByKeyValueData1 = chartData['chart_type_json']['x_group'] ?? '';
}
List<dynamic> responseData = chartData['response'];
List<BarChartGroupData> barGroups = [];
@ -3356,7 +3384,7 @@ class ChartWidget extends StatelessWidget {
// Filter data for the current group
List<dynamic> groupData = responseData.where((entry) {
return entry['ObsKey'][chartData['group_by']] == groupValue;
return entry['ObsKey'][groupByKeyValueData1] == groupValue;
}).toList();
Map<String, String> genderMapping = {

View File

@ -9,11 +9,25 @@ class InternetCheckScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Listen to changes in connectivity and navigate back to Home if online
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == true) {
Navigator.pop(context);
// context.go('/myhomepage');
// Show a SnackBar when internet is back
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Internet is back!"),
backgroundColor: Colors.green,
),
);
context.pop();
// Wait for the SnackBar to be visible before navigating
// Future.delayed(Duration(seconds: 1), () {
// if (context.canPop()) {
// context.pop(); // Go back if there's a previous page
// } else {
// context.go(
// '/myhomepage'); // Redirect to home if no previous page exists
// }
// });
}
});
@ -41,8 +55,20 @@ class InternetCheckScreen extends ConsumerWidget {
await InternetConnectionChecker.instance.hasConnection;
if (hasInternet) {
Navigator.pop(
context); // Redirect to home if internet is available
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Internet is back!"),
backgroundColor: Colors.green,
),
);
context.pop();
// Future.delayed(Duration(seconds: 1), () {
// if (context.canPop()) {
// context.pop();
// } else {
// context.go('/myhomepage');
// }
// });
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(

View File

@ -473,7 +473,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
// If no internet, redirect to InternetCheckScreen
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.go('/internetcheck');
context.push('/internetcheck');
}
});
final profileLocale = ref.watch(localeProvider);

View File

@ -10,6 +10,7 @@ import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:the_validator/the_validator.dart';
import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/my_theme.dart';
import 'package:uae_stat/domain/use_cases/auth_use_case.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
@ -46,7 +47,7 @@ class LoginRoute extends HookConsumerWidget {
// final FirebaseAuth _auth = FirebaseAuth.instance;
static final formKey = GlobalKey<FormState>();
Future<bool> profileStatus(String userId) async {
Future<bool> profileStatus(String userId, WidgetRef ref) async {
try {
// Authenticate admin
final adminAuth = await pb.admins.authWithPassword(
@ -71,6 +72,9 @@ class LoginRoute extends HookConsumerWidget {
final bool? isVerified = userDetailsResponse.data['verified'];
final bool? isUserMailVerified =
userDetailsResponse.data['user_mail_verify'];
final preferredLanguage = userDetailsResponse.data['language'] ?? '';
print('preferredLanguage login $preferredLanguage');
// Check admin and email verification statuses
if (isVerified == false) {
@ -79,6 +83,14 @@ class LoginRoute extends HookConsumerWidget {
if (isUserMailVerified == false) {
throw Exception('Email not verified');
}
// **Set Default Locale in Provider**
if (preferredLanguage == 'ar') {
ref.read(localeProvider.notifier).setLocale(const Locale('ar'));
} else {
ref.read(localeProvider.notifier).setLocale(const Locale('en'));
}
userData = userDetailsResponse;
// Check if 'is_profile_completed' is true
final bool isProfileCompleted =
@ -226,6 +238,12 @@ class LoginRoute extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
final hasValidated = useState(false);
final locale = ref.watch(localeProvider);
final emailCtl = useTextEditingController();
@ -467,7 +485,7 @@ class LoginRoute extends HookConsumerWidget {
await getDeviceToken(context, userId);
}
try {
final bool isProfileComplete = await profileStatus(userId);
final bool isProfileComplete = await profileStatus(userId, ref);
print("Is Profile Complete: $isProfileComplete");
// Extract intendedPath from query parameters (if coming from redirect)

View File

@ -401,11 +401,13 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
ref.read(homeTourProvider.notifier).state = true;
ref.read(chartsTourProvider.notifier).state = false;
debugPrint('Home Tutorial Finished');
locale.languageCode == 'ar'?
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=null&title=المنشآت الفندقية',):
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',);
locale.languageCode == 'ar'
? context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=null&title=المنشآت الفندقية',
)
: context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',
);
},
)..show(context: context);
} else if (!previousHomeTour) {
@ -419,11 +421,13 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
onFinish: () {
ref.read(previousHomeTourProvider.notifier).state = true;
debugPrint('Previous Home Tutorial Finished');
locale.languageCode == 'ar'?
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=null&title=المنشآت الفندقية',):
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',);
locale.languageCode == 'ar'
? context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=null&title=المنشآت الفندقية',
)
: context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',
);
},
)..show(context: context);
}
@ -821,11 +825,13 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
.read(
chartsTourProvider.notifier)
.state = false;
locale.languageCode == 'ar'?
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=null&title=المنشآت الفندقية',):
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',);
locale.languageCode == 'ar'
? context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=null&title=المنشآت الفندقية',
)
: context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',
);
} else {
tutorialCoachMark.next();
}
@ -1149,7 +1155,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
// If no internet, redirect to InternetCheckScreen
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.go('/internetcheck');
context.push('/internetcheck');
}
});
@ -1161,7 +1167,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
} else if (data.isEmpty) {
return Center(child: Text("No data available"));
}
String firstMainTopic=data.first['main_topic']??'';
String firstMainTopic = data.first['main_topic'] ?? '';
return Container(
height: myheight,
// color: Colors.cyan,

View File

@ -101,23 +101,28 @@ class _BookMarkState extends ConsumerState<BookMark> {
// print('dataList $dataList');
});
List<Map<String, dynamic>> transformAndStore(List<Map<String, dynamic>> fetchedData) {
List<Map<String, dynamic>> transformAndStore(
List<Map<String, dynamic>> fetchedData) {
// Define the required order
List<String> order = [context.translate('ECONOMY','اقتصاد'), context.translate('SOCIAL', 'اجتماعي'), context.translate('ENVIRONMENT', 'بيئة')];
List<String> order = [
context.translate('ECONOMY', 'اقتصاد'),
context.translate('SOCIAL', 'اجتماعي'),
context.translate('ENVIRONMENT', 'بيئة')
];
// Create a list to store sorted data
List<Map<String, dynamic>> sortedList = [];
// Group data based on categories
Map<String, List<Map<String, dynamic>>> groupedData = {
context.translate('ECONOMY','اقتصاد'): [],
context.translate('ECONOMY', 'اقتصاد'): [],
context.translate('SOCIAL', 'اجتماعي'): [],
context.translate('ENVIRONMENT', 'بيئة'): []
};
// Categorize data
for (var item in fetchedData) {
String mainTopic = item["main_topic"]?.toString()?? "";
String mainTopic = item["main_topic"]?.toString() ?? "";
if (groupedData.containsKey(mainTopic)) {
groupedData[mainTopic]!.add(item);
}
@ -133,6 +138,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
// Store the sorted list (replace this with your storage method)
return sortedList;
}
setState(() {
dataList = transformAndStore(dataList);
});
@ -309,12 +315,9 @@ class _BookMarkState extends ConsumerState<BookMark> {
@override
Widget build(BuildContext context) {
final isConnected = ref.watch(connectivityProvider);
// If no internet, redirect to InternetCheckScreen
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.go('/internetcheck');
context.push('/internetcheck');
}
});

View File

@ -1,22 +1,31 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/enquiry_asset_icon_path.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:flutter_svg/flutter_svg.dart';
class Contact extends StatefulWidget {
class Contact extends ConsumerStatefulWidget {
const Contact({super.key});
@override
State<Contact> createState() => _ContactState();
ConsumerState<Contact> createState() => _ContactState();
}
class _ContactState extends State<Contact> {
class _ContactState extends ConsumerState<Contact> {
@override
Widget build(BuildContext context) {
final double screenWidth = MediaQuery.of(context).size.width;
// final double screenHeight = MediaQuery.of(context).size.height;
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
return BaseScaffold(
body: Container(
color: Colors.grey[200],
@ -30,13 +39,41 @@ class _ContactState extends State<Contact> {
title: 'DUBAI - EMIRATES TOWER -32ND FLOOR',
titleAr: 'دبي - أبراج الإمارات - الطابق 32',
details: [
{'icon': EnquiryAssetIconPath.building, 'text': 'Office : Dubai - Emirates Tower -32nd Floor', 'textAr': 'المقر الرئيسي : دبي - أبراج الإمارات - الطابق 32'},
{'icon': EnquiryAssetIconPath.phone, 'text': 'Tel : 00971 46080000', 'textAr': 'الهاتف : 0097146080000'},
{'icon': EnquiryAssetIconPath.fax, 'text': 'Fax : 0097143273535', 'textAr': 'فاكس : 0097143273535'},
{'icon': EnquiryAssetIconPath.map, 'text': 'P.O.Box : 127000 Dubai', 'textAr': 'ص.ب: : 127000 دبي'},
{'icon': EnquiryAssetIconPath.at, 'text': 'Email Address : info@fcsc.gov.ae', 'textAr': 'البريد الإلكتروني : info@fcsc.gov.ae'},
{'icon': EnquiryAssetIconPath.map, 'text': 'Latitude : 25.223926', 'textAr': 'خط العرض : 25.223926'},
{'icon': EnquiryAssetIconPath.map, 'text': 'Longitude : 55.350526', 'textAr': 'خط الطول : 55.350526'},
{
'icon': EnquiryAssetIconPath.building,
'text': 'Office : Dubai - Emirates Tower -32nd Floor',
'textAr': 'المقر الرئيسي : دبي - أبراج الإمارات - الطابق 32'
},
{
'icon': EnquiryAssetIconPath.phone,
'text': 'Tel : 00971 46080000',
'textAr': 'الهاتف : 0097146080000'
},
{
'icon': EnquiryAssetIconPath.fax,
'text': 'Fax : 0097143273535',
'textAr': 'فاكس : 0097143273535'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'P.O.Box : 127000 Dubai',
'textAr': 'ص.ب: : 127000 دبي'
},
{
'icon': EnquiryAssetIconPath.at,
'text': 'Email Address : info@fcsc.gov.ae',
'textAr': 'البريد الإلكتروني : info@fcsc.gov.ae'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'Latitude : 25.223926',
'textAr': 'خط العرض : 25.223926'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'Longitude : 55.350526',
'textAr': 'خط الطول : 55.350526'
},
],
),
const SizedBox(height: 10),
@ -45,13 +82,41 @@ class _ContactState extends State<Contact> {
title: 'MEDIA SECTION',
titleAr: 'قسم الاعلام',
details: [
{'icon': EnquiryAssetIconPath.building, 'text': 'Office : Media Section', 'textAr': 'المقر الرئيسي : قسم الاعلام'},
{'icon': EnquiryAssetIconPath.phone, 'text': 'Tel : 00971 46080000', 'textAr': 'الهاتف : 0097146080000'},
{'icon': EnquiryAssetIconPath.fax, 'text': 'Fax : 0097143273535', 'textAr': 'فاكس : 0097143273535'},
{'icon': EnquiryAssetIconPath.map, 'text': 'P.O.Box : 127000 Dubai', 'textAr': 'ص.ب: : 127000 دبي'},
{'icon': EnquiryAssetIconPath.at, 'text': 'Email Address : GCO@fcsc.gov.ae', 'textAr': 'البريد الإلكتروني : GCO@fcsc.gov.ae'},
{'icon': EnquiryAssetIconPath.map, 'text': 'Latitude : 25.223926', 'textAr': 'خط العرض : 25.223926'},
{'icon': EnquiryAssetIconPath.map, 'text': 'Longitude : 55.350526', 'textAr': 'خط الطول : 55.350526'},
{
'icon': EnquiryAssetIconPath.building,
'text': 'Office : Media Section',
'textAr': 'المقر الرئيسي : قسم الاعلام'
},
{
'icon': EnquiryAssetIconPath.phone,
'text': 'Tel : 00971 46080000',
'textAr': 'الهاتف : 0097146080000'
},
{
'icon': EnquiryAssetIconPath.fax,
'text': 'Fax : 0097143273535',
'textAr': 'فاكس : 0097143273535'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'P.O.Box : 127000 Dubai',
'textAr': 'ص.ب: : 127000 دبي'
},
{
'icon': EnquiryAssetIconPath.at,
'text': 'Email Address : GCO@fcsc.gov.ae',
'textAr': 'البريد الإلكتروني : GCO@fcsc.gov.ae'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'Latitude : 25.223926',
'textAr': 'خط العرض : 25.223926'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'Longitude : 55.350526',
'textAr': 'خط الطول : 55.350526'
},
],
),
const SizedBox(height: 10),
@ -60,13 +125,41 @@ class _ContactState extends State<Contact> {
title: 'SGDS',
titleAr: 'أهداف التنمية المستدامة',
details: [
{'icon': EnquiryAssetIconPath.building, 'text': 'Office : SDGs', 'textAr': 'المقر الرئيسي : أهداف التنمية المستدامة'},
{'icon': EnquiryAssetIconPath.phone, 'text': 'Tel : 00971 46080000', 'textAr': 'الهاتف : 0097146080000'},
{'icon': EnquiryAssetIconPath.fax, 'text': 'Fax : 0097143273535', 'textAr': 'فاكس : 0097143273535'},
{'icon': EnquiryAssetIconPath.map, 'text': 'P.O.Box : 127000 Dubai', 'textAr': 'ص.ب: : 127000 دبي'},
{'icon': EnquiryAssetIconPath.at, 'text': 'Email Address : sdgs@fcsc.gov.ae', 'textAr': 'البريد الإلكتروني : sdgs@fcsc.gov.ae'},
{'icon': EnquiryAssetIconPath.map, 'text': 'Latitude : 25.223926', 'textAr': 'خط العرض : 25.223926'},
{'icon': EnquiryAssetIconPath.map, 'text': 'Longitude : 55.350526', 'textAr': 'خط الطول : 55.350526'},
{
'icon': EnquiryAssetIconPath.building,
'text': 'Office : SDGs',
'textAr': 'المقر الرئيسي : أهداف التنمية المستدامة'
},
{
'icon': EnquiryAssetIconPath.phone,
'text': 'Tel : 00971 46080000',
'textAr': 'الهاتف : 0097146080000'
},
{
'icon': EnquiryAssetIconPath.fax,
'text': 'Fax : 0097143273535',
'textAr': 'فاكس : 0097143273535'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'P.O.Box : 127000 Dubai',
'textAr': 'ص.ب: : 127000 دبي'
},
{
'icon': EnquiryAssetIconPath.at,
'text': 'Email Address : sdgs@fcsc.gov.ae',
'textAr': 'البريد الإلكتروني : sdgs@fcsc.gov.ae'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'Latitude : 25.223926',
'textAr': 'خط العرض : 25.223926'
},
{
'icon': EnquiryAssetIconPath.map,
'text': 'Longitude : 55.350526',
'textAr': 'خط الطول : 55.350526'
},
],
),
],
@ -76,8 +169,11 @@ class _ContactState extends State<Contact> {
title: Text(context.translate('Contact Us', 'اتصل بنا')),
);
}
Widget buildContactCard(BuildContext context, {required String title, required String titleAr, required List<Map<String, String>> details}) {
Widget buildContactCard(BuildContext context,
{required String title,
required String titleAr,
required List<Map<String, String>> details}) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
decoration: BoxDecoration(
@ -103,12 +199,13 @@ class _ContactState extends State<Contact> {
),
),
const SizedBox(height: 8),
...details.map((item) => buildTextRow(item['icon']!, context.translate(item['text']!, item['textAr']!))),
...details.map((item) => buildTextRow(item['icon']!,
context.translate(item['text']!, item['textAr']!))),
],
),
);
}
Widget buildTextRow(String iconName, String text) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
@ -134,4 +231,4 @@ class _ContactState extends State<Contact> {
),
);
}
}
}

View File

@ -5,6 +5,7 @@ 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:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
@ -13,19 +14,20 @@ import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.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/routes/drawer_routes/custom_drawer_routes.dart';
class EditProfile extends StatefulWidget {
class EditProfile extends ConsumerStatefulWidget {
const EditProfile({super.key});
@override
State<EditProfile> createState() => _EditProfileState();
ConsumerState<EditProfile> createState() => _EditProfileState();
}
class _EditProfileState extends State<EditProfile> {
class _EditProfileState extends ConsumerState<EditProfile> {
final _pb = PocketBase(apiUrl);
// final _pb = PocketBase('http://127.0.0.1:8090');
bool _isProfileCompleted = false;
@ -459,6 +461,11 @@ class _EditProfileState extends State<EditProfile> {
@override
Widget build(BuildContext context) {
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
return PopScope(
canPop: false, // Allow back navigation only if not login screen
onPopInvokedWithResult: (didPop, result) {

View File

@ -8,6 +8,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/feedback_asset_path.dart';
@ -21,17 +22,16 @@ import '../../../../config/my_theme.dart';
import '../../../../domain/use_cases/preferences_use_case.dart';
import '../../../components/my_toggle.dart';
class FeedbackForm extends StatefulWidget {
class FeedbackForm extends ConsumerStatefulWidget {
const FeedbackForm({super.key});
@override
_FeedbackFormState createState() => _FeedbackFormState();
ConsumerState<FeedbackForm> createState() => _FeedbackFormState();
}
class _FeedbackFormState extends State<FeedbackForm>
class _FeedbackFormState extends ConsumerState<FeedbackForm>
with WidgetsBindingObserver {
final _pb =
PocketBase(apiUrl); // Initialize PocketBase client
final _pb = PocketBase(apiUrl); // Initialize PocketBase client
// final _pb =
// PocketBase('http://127.0.0.1:8090'); // Initialize PocketBase client
@ -237,6 +237,12 @@ class _FeedbackFormState extends State<FeedbackForm>
// final uri = Uri.parse(GoRouterState.of(context).uri.toString());
// final userName = uri.queryParameters['userName'] ?? 'Guest User';
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
final userName = GoRouterState.of(context).extra as String? ?? 'Guest User';
return PopScope(
canPop: false, // Allow back navigation only if not login screen

View File

@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
@ -11,13 +13,13 @@ import 'package:uae_stat/presentation/components/my_drawer.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class ManageUserRouter extends StatefulWidget {
class ManageUserRouter extends ConsumerStatefulWidget {
late final Widget title;
@override
State<ManageUserRouter> createState() => _ManageUserRouterState();
ConsumerState<ManageUserRouter> createState() => _ManageUserRouterState();
}
class _ManageUserRouterState extends State<ManageUserRouter> {
class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
final _pb = PocketBase(apiUrl);
List<User> userData = [];
int _sortColumnIndex = 0;
@ -270,6 +272,12 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
@override
Widget build(BuildContext context) {
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
final Map<String, String> statusOptions = {
'Approved': AppLocalizations.of(context)!.approved,
'Denied': AppLocalizations.of(context)!.denied,

View File

@ -7,6 +7,7 @@ import 'package:intl/intl.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import '../../custom_drawer_routes.dart';
@ -123,6 +124,12 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
@override
Widget build(BuildContext context) {
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
ref.listen<Locale?>(localeProvider, (previous, next) {
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
fetchNotifications(localeCode);
@ -299,18 +306,20 @@ class NotificationTile extends StatelessWidget {
print('isPushed $isPushed , $id');
return GestureDetector(
onTap: () {
readedNotification(userID, id);
final encodedKey = Uri.encodeQueryComponent('notification');
context.push('/notification_details', extra: {
'title': title,
'message': message,
'date': date,
'category': category,
'id': id,
'backNavigation': encodedKey
});
},
onTap: isPushed
? () {
readedNotification(userID, id);
final encodedKey = Uri.encodeQueryComponent('notification');
context.go('/notification_details', extra: {
'title': title,
'message': message,
'date': date,
'category': category,
'id': id,
'backNavigation': encodedKey
});
}
: null,
child: ListTile(
leading: isPushed
? const Icon(Icons.circle, size: 12, color: Color(0xFFFF274E))

View File

@ -5,6 +5,7 @@ import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import '../../custom_drawer_routes.dart';
@ -98,6 +99,12 @@ class _NotificationDetailsState extends ConsumerState<NotificationDetails> {
@override
Widget build(BuildContext context) {
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
if (hasInternet.value == false) {
context.push('/internetcheck');
}
});
ref.listen<Locale?>(localeProvider, (previous, next) {
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
fetchNotifications(localeCode);

View File

@ -667,11 +667,11 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
}
});
// **Set Default Locale in Provider**
if (preferredLanguage == 'ar') {
ref.read(localeProvider.notifier).setLocale(const Locale('ar'));
} else {
ref.read(localeProvider.notifier).setLocale(const Locale('en'));
}
// if (preferredLanguage == 'ar') {
// ref.read(localeProvider.notifier).setLocale(const Locale('ar'));
// } else {
// ref.read(localeProvider.notifier).setLocale(const Locale('en'));
// }
} catch (e) {
print('Error fetching user details: $e');
}
@ -784,7 +784,13 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
color: widget.colorChange ? Colors.white : Colors.black,
icon: const Icon(Icons.arrow_back_ios_new, size: 24),
onPressed: () {
if (widget.navBackArrow is Text &&
(widget.navBackArrow as Text).data ==
'notification') {
context.go('/notification');
} else {
context.pop();
}
},
),
),
@ -1203,7 +1209,8 @@ void _showLogoutConfirmationDialog(BuildContext context) {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 120, // Set button width
width:
MediaQuery.of(context).size.width * 0.3, // Set button width
child: TextButton(
onPressed: () => Navigator.pop(dialogContext),
style: TextButton.styleFrom(
@ -1226,7 +1233,8 @@ void _showLogoutConfirmationDialog(BuildContext context) {
),
SizedBox(width: 16),
SizedBox(
width: 120, // Set button width
width:
MediaQuery.of(context).size.width * 0.3, // Set button width
child: TextButton(
onPressed: () => logout(context),
style: TextButton.styleFrom(

View File

@ -93,18 +93,18 @@ packages:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
url: "https://pub.dev"
source: hosted
version: "2.11.0"
version: "2.12.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
boxy:
dependency: "direct main"
description:
@ -181,10 +181,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
checked_yaml:
dependency: transitive
description:
@ -213,10 +213,10 @@ packages:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
code_builder:
dependency: transitive
description:
@ -229,10 +229,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.19.0"
version: "1.19.1"
connectivity_plus:
dependency: "direct main"
description:
@ -404,10 +404,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
fast_immutable_collections:
dependency: "direct main"
description:
@ -952,18 +952,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
url: "https://pub.dev"
source: hosted
version: "10.0.7"
version: "10.0.8"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.dev"
source: hosted
version: "3.0.8"
version: "3.0.9"
leak_tracker_testing:
dependency: transitive
description:
@ -1008,10 +1008,10 @@ packages:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.17"
material_charts:
dependency: "direct main"
description:
@ -1032,10 +1032,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev"
source: hosted
version: "1.15.0"
version: "1.16.0"
mime:
dependency: transitive
description:
@ -1088,10 +1088,10 @@ packages:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
path_parsing:
dependency: transitive
description:
@ -1411,10 +1411,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.10.1"
sprintf:
dependency: transitive
description:
@ -1427,10 +1427,10 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.12.1"
state_notifier:
dependency: transitive
description:
@ -1443,10 +1443,10 @@ packages:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
stream_transform:
dependency: transitive
description:
@ -1459,10 +1459,10 @@ packages:
dependency: transitive
description:
name: string_scanner
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.1"
syncfusion_flutter_charts:
dependency: "direct main"
description:
@ -1483,18 +1483,18 @@ packages:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
test_api:
dependency: transitive
description:
name: test_api
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.dev"
source: hosted
version: "0.7.3"
version: "0.7.4"
the_validator:
dependency: "direct main"
description:
@ -1683,10 +1683,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
url: "https://pub.dev"
source: hosted
version: "14.3.0"
version: "14.3.1"
watcher:
dependency: transitive
description:
@ -1784,5 +1784,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.6.0 <4.0.0"
dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.27.0"

View File

@ -1,7 +1,7 @@
name: uae_stat
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
publish_to: "none"
version: 1.0.33+34
version: 1.0.35+36
environment:
sdk: ">=3.2.3 <4.0.0"