bug fix and forgot password
This commit is contained in:
parent
a0d7a733a4
commit
efb0d38664
@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) {
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = "43"
|
||||
flutterVersionCode = "44"
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = "1.0.42"
|
||||
flutterVersionName = "1.0.43"
|
||||
}
|
||||
|
||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||
|
||||
@ -30,13 +30,27 @@
|
||||
<meta-data android:name="flutter_deeplinking_enabled"
|
||||
android:value="true"/>
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="https" android:host="www.fcsc.com"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="fcsc-a161c.web.app"
|
||||
android:scheme="flutterdeeplink"
|
||||
android:host="fcsc"
|
||||
android:pathPrefix="/login" />
|
||||
<data
|
||||
android:scheme="flutterdeeplink"
|
||||
android:host="fcsc"
|
||||
android:pathPrefix="/chartScreen"/>
|
||||
<data
|
||||
android:scheme="flutterdeeplink"
|
||||
android:host="fcsc"
|
||||
android:pathPrefix="/forgot-password"/>
|
||||
</intent-filter>
|
||||
<!-- <intent-filter >-->
|
||||
<!-- <action android:name="android.intent.action.VIEW" />-->
|
||||
|
||||
@ -667,7 +667,8 @@ final GoRouter router = GoRouter(
|
||||
redirect: (context, state) async {
|
||||
if (state.uri.path == '/SessionCheckScreen' ||
|
||||
state.uri.path == '/login' ||
|
||||
state.uri.path == '/register') {
|
||||
state.uri.path == '/register' ||
|
||||
state.uri.path == '/forgot-password/:email') {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -240,7 +240,8 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
|
||||
onChanged: (value) {
|
||||
filterData(
|
||||
value); // Call filter function directly on input change
|
||||
},
|
||||
}, // Ensures vertical alignment
|
||||
// Centers text horizontally
|
||||
decoration: InputDecoration(
|
||||
hintText: AppLocalizations.of(context)!.search,
|
||||
hintStyle: TextStyle(color: Color(0xFFAA8E83)),
|
||||
@ -261,8 +262,9 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
|
||||
// // fit: BoxFit.contain,
|
||||
// ),
|
||||
border: InputBorder.none,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(vertical: 9, horizontal: 18.0),
|
||||
// contentPadding:
|
||||
// EdgeInsets.symmetric(vertical: 9, horizontal: 18.0),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -107,6 +107,66 @@ class _ForgotPasswordState extends ConsumerState<ForgotPassword> {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Future<void> updatePassword(
|
||||
// String email, String oldPassword, String newPassword) async {
|
||||
// print(email);
|
||||
// try {
|
||||
// setState(() {
|
||||
// isLoading = true;
|
||||
// });
|
||||
// // Authenticate as admin
|
||||
// final adminAuth = await _pb.admins
|
||||
// .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||
// final token = adminAuth.token;
|
||||
//
|
||||
// final headers = {
|
||||
// 'Authorization': 'Bearer $token',
|
||||
// };
|
||||
//
|
||||
// // Update password
|
||||
// await _pb.collection('users').update(
|
||||
// email,
|
||||
// body: {
|
||||
// 'password': newPassword,
|
||||
// 'passwordConfirm': newPassword,
|
||||
// },
|
||||
// headers: headers,
|
||||
// );
|
||||
//
|
||||
// setState(() {
|
||||
// isLoading = false;
|
||||
// _isPasswordUpdated = true;
|
||||
// });
|
||||
//
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// content:
|
||||
// Text(AppLocalizations.of(context)!.password_update_successfully),
|
||||
// backgroundColor: Colors.green,
|
||||
// ),
|
||||
// );
|
||||
//
|
||||
// print('_isPasswordUpdated $_isPasswordUpdated');
|
||||
//
|
||||
// // Navigator.push(
|
||||
// // context,
|
||||
// // MaterialPageRoute(
|
||||
// // builder: (context) => ProfileScreen(userId: userId)),
|
||||
// // );
|
||||
// } catch (e) {
|
||||
// setState(() {
|
||||
// isLoading = false;
|
||||
// });
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// content: Text(context.translate(
|
||||
// 'Failed to update password: $e', 'فشل في تحديث كلمة المرور')),
|
||||
// backgroundColor: Colors.red,
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<void> updatePassword(
|
||||
String email, String oldPassword, String newPassword) async {
|
||||
try {
|
||||
@ -122,9 +182,27 @@ class _ForgotPasswordState extends ConsumerState<ForgotPassword> {
|
||||
'Authorization': 'Bearer $token',
|
||||
};
|
||||
|
||||
// Update password
|
||||
// Step 1: Find User by Email
|
||||
final result = await _pb.collection('users').getList(
|
||||
filter: 'email = "$email"',
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (result.items.isEmpty) {
|
||||
// throw Exception("User not found");
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('User not found'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final userId = result.items.first.id;
|
||||
|
||||
// Step 3: Update Password
|
||||
await _pb.collection('users').update(
|
||||
email,
|
||||
userId,
|
||||
body: {
|
||||
'password': newPassword,
|
||||
'passwordConfirm': newPassword,
|
||||
@ -146,19 +224,14 @@ class _ForgotPasswordState extends ConsumerState<ForgotPassword> {
|
||||
);
|
||||
|
||||
print('_isPasswordUpdated $_isPasswordUpdated');
|
||||
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => ProfileScreen(userId: userId)),
|
||||
// );
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(context.translate('Failed to update password: $e','فشل في تحديث كلمة المرور')),
|
||||
content: Text('Failed to update password: $e'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
|
||||
@ -2695,50 +2695,54 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> shareCurrentPage(BuildContext context, bool _isSharing) async {
|
||||
if (_isSharing) return; // Prevent multiple taps
|
||||
Future<void> shareCurrentPage(BuildContext context, bool isSharing) async {
|
||||
if (isSharing) return; // Prevent multiple taps
|
||||
|
||||
_isSharing = true;
|
||||
isSharing = true;
|
||||
try {
|
||||
final String currentRoute = GoRouterState.of(context).uri.toString();
|
||||
final String baseAppLink = 'https://fcsc-a161c.web.app';
|
||||
final String baseAppLink = 'https://www.fcsc.com';
|
||||
final String shareLink = '$baseAppLink$currentRoute';
|
||||
final String shareText = 'Check this out!';
|
||||
final String svgAssetPath = 'assets/backgrounds/share/fcsc.svg';
|
||||
final String shareText = 'Check this out!\n\n$shareLink';
|
||||
print('Generated Share Link: $shareLink');
|
||||
|
||||
// Optional: Capture SVG to image
|
||||
final String svgAssetPath = 'assets/backgrounds/share/fcsc.svg';
|
||||
final screenshotController = ScreenshotController();
|
||||
final svgWidget = SvgPicture.asset(
|
||||
svgAssetPath,
|
||||
width: 200,
|
||||
height: 200,
|
||||
);
|
||||
|
||||
final Uint8List? capturedImage =
|
||||
await screenshotController.captureFromWidget(
|
||||
Material(child: svgWidget),
|
||||
);
|
||||
|
||||
if (capturedImage == null) {
|
||||
throw Exception('Failed to capture SVG as image');
|
||||
}
|
||||
|
||||
print('SVG capture failed, proceeding without image.');
|
||||
await Share.share(shareText, subject: 'App Link');
|
||||
} else {
|
||||
final directory = await getTemporaryDirectory();
|
||||
final file = File('${directory.path}/share.svg');
|
||||
final file = File('${directory.path}/share_image.png');
|
||||
await file.writeAsBytes(capturedImage);
|
||||
|
||||
await Share.shareXFiles(
|
||||
[XFile(file.path)],
|
||||
text: '$shareText\n$shareLink',
|
||||
text: shareText,
|
||||
subject: 'Shared Content',
|
||||
);
|
||||
|
||||
await file.delete();
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error sharing file: $e");
|
||||
print("Error sharing content: $e");
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Error sharing: $e')),
|
||||
SnackBar(content: Text('Error sharing: ${e.toString()}')),
|
||||
);
|
||||
} finally {
|
||||
_isSharing = false; // Reset flag after sharing completes
|
||||
isSharing = false; // Reset flag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import 'dart:math';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
// import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
|
||||
class ChartWidget extends StatelessWidget {
|
||||
@ -208,8 +209,7 @@ class ChartWidget extends StatelessWidget {
|
||||
x: entry['ObsKey']['TIME_PERIOD'],
|
||||
y: double.tryParse(entry['ObsValue']['Value']) ?? 0.0,
|
||||
);
|
||||
})
|
||||
.toList();
|
||||
}).toList();
|
||||
}
|
||||
|
||||
List<BarChartGroupData> parseColumnChartData(dynamic chartData) {
|
||||
@ -380,7 +380,8 @@ class ChartWidget extends StatelessWidget {
|
||||
// ];
|
||||
// }
|
||||
|
||||
List<Widget> generateIndicators(dynamic chartData, double totalValue) {
|
||||
List<Widget> generateIndicators(
|
||||
dynamic chartData, double totalValue, BuildContext context) {
|
||||
var groupByKeyValue;
|
||||
if (chartData['chart_type_json']['chart_type'] == 'bar_chart_horizontal' ||
|
||||
chartData['chart_type_json']['chart_type'] == 'horizontal_rotate') {
|
||||
@ -412,50 +413,83 @@ class ChartWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
// double percentage = (value / totalValue) * 100;
|
||||
String percentage =
|
||||
(totalValue > 0)
|
||||
String percentage = (totalValue > 0)
|
||||
? ((value / totalValue) * 100).toStringAsFixed(1)
|
||||
: "0.0";
|
||||
// bool isTouched = index == touchedIndex;
|
||||
|
||||
// return Wrap(
|
||||
// alignment: WrapAlignment.center,
|
||||
// spacing: 12,
|
||||
// runSpacing: 8,
|
||||
// children: [
|
||||
// Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// Container(
|
||||
// width: 10,
|
||||
// height: 10,
|
||||
// decoration: BoxDecoration(
|
||||
// color: uniqueColors[index % uniqueColors.length],
|
||||
// shape: BoxShape.circle,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Flexible(
|
||||
// child: Text(
|
||||
// context.translate(
|
||||
// '$title -- $percentage%',
|
||||
// '$title -- %$percentage',
|
||||
// ),
|
||||
// textAlign: TextAlign.start,
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// softWrap: true,
|
||||
// maxLines: 2, // Allows wrapping within two lines
|
||||
// overflow: TextOverflow.ellipsis, // Prevents overflow
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start, // Aligns dot to text start
|
||||
children: [
|
||||
Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
margin: EdgeInsets.only(top: 4), // Adjust to align with text
|
||||
decoration: BoxDecoration(
|
||||
color: uniqueColors[index % uniqueColors.length],
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
TooltipTheme(
|
||||
Expanded(
|
||||
child: TooltipTheme(
|
||||
data: TooltipThemeData(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blueGrey[800], // Change background color
|
||||
borderRadius: BorderRadius.circular(
|
||||
8,
|
||||
), // Optional: rounded corners
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
textStyle: TextStyle(color: Colors.white), // Change text color
|
||||
textStyle: TextStyle(color: Colors.white),
|
||||
),
|
||||
child: Tooltip(
|
||||
message: title, // Full text on hover
|
||||
child: ConstrainedBox(
|
||||
// Constrain width to allow wrapping
|
||||
constraints: BoxConstraints(maxWidth: 250),
|
||||
child: Text(
|
||||
context.translate(
|
||||
'$title -- $percentage%',
|
||||
'$title -- %$percentage',
|
||||
),
|
||||
style: TextStyle(fontSize: 12),
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
// overflow: TextOverflow.ellipsis, // Ensures text doesn't overflow
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
],
|
||||
);
|
||||
}).toList();
|
||||
@ -618,8 +652,7 @@ class ChartWidget extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
case 'pie_chart':
|
||||
double totalValue = chartData['response']
|
||||
.map<double>((entry) {
|
||||
double totalValue = chartData['response'].map<double>((entry) {
|
||||
var value = entry['ObsValue']['Value'];
|
||||
// print('Processing value: $value, type: ${value.runtimeType}');
|
||||
return (value is num)
|
||||
@ -627,8 +660,7 @@ class ChartWidget extends StatelessWidget {
|
||||
: value is String
|
||||
? double.tryParse(value) ?? 0.0
|
||||
: 0.0;
|
||||
})
|
||||
.fold(0.0, (prev, element) => prev + element);
|
||||
}).fold(0.0, (prev, element) => prev + element);
|
||||
|
||||
ValueNotifier<int?> touchedIndex = ValueNotifier(null);
|
||||
|
||||
@ -665,10 +697,8 @@ class ChartWidget extends StatelessWidget {
|
||||
touchCallback: (FlTouchEvent event, pieTouchResponse) {
|
||||
if (pieTouchResponse?.touchedSection != null &&
|
||||
event is! FlTapUpEvent) {
|
||||
touchedIndex.value =
|
||||
pieTouchResponse!
|
||||
.touchedSection!
|
||||
.touchedSectionIndex;
|
||||
touchedIndex.value = pieTouchResponse!
|
||||
.touchedSection!.touchedSectionIndex;
|
||||
} else {
|
||||
touchedIndex.value =
|
||||
null; // Reset when not touching
|
||||
@ -704,7 +734,8 @@ class ChartWidget extends StatelessWidget {
|
||||
child: Column(
|
||||
// Change Row to Column
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: generateIndicators(chartData, totalValue),
|
||||
children:
|
||||
generateIndicators(chartData, totalValue, context),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -870,8 +901,7 @@ class ChartWidget extends StatelessWidget {
|
||||
child: Wrap(
|
||||
spacing: 10, // Horizontal spacing between items
|
||||
runSpacing: 5, // Vertical spacing between rows
|
||||
children:
|
||||
chunkedGroupByValues.expand((chunk) {
|
||||
children: chunkedGroupByValues.expand((chunk) {
|
||||
return chunk.map((group) {
|
||||
List<String> groupByValuesList = groupByValues.toList();
|
||||
int index = groupByValuesList.indexOf(group);
|
||||
@ -938,8 +968,7 @@ class ChartWidget extends StatelessWidget {
|
||||
print('LnTrnd1');
|
||||
|
||||
// Extract all years from the chart data
|
||||
List<int> years =
|
||||
(chartData['response'] as List<dynamic>)
|
||||
List<int> years = (chartData['response'] as List<dynamic>)
|
||||
.map<int>(
|
||||
(entry) =>
|
||||
int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
|
||||
@ -974,8 +1003,7 @@ class ChartWidget extends StatelessWidget {
|
||||
// Filter chart data to only include entries within the last 5 years
|
||||
List<dynamic> filteredData =
|
||||
(chartData['response'] as List<dynamic>).where((entry) {
|
||||
int year =
|
||||
int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
|
||||
int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
|
||||
return year >= minYear && year <= maxYear;
|
||||
}).toList();
|
||||
print('LnTrnd2 $filteredData');
|
||||
@ -985,8 +1013,7 @@ class ChartWidget extends StatelessWidget {
|
||||
// (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
|
||||
// .toSet();
|
||||
|
||||
Set<String> uniqueXValues =
|
||||
filteredData.map<String>((entry) {
|
||||
Set<String> uniqueXValues = filteredData.map<String>((entry) {
|
||||
String? timePeriod =
|
||||
entry['ObsKey']['TIME_PERIOD']; // Nullable String
|
||||
print('TIME_PERIOD- $timePeriod');
|
||||
@ -1050,8 +1077,7 @@ class ChartWidget extends StatelessWidget {
|
||||
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
|
||||
}
|
||||
|
||||
Set<double> uniqueXValuesProcessed =
|
||||
uniqueXValues
|
||||
Set<double> uniqueXValuesProcessed = uniqueXValues
|
||||
.where((value) => value.isNotEmpty) // Remove any empty strings
|
||||
.map(parseTimePeriod)
|
||||
.toSet();
|
||||
@ -1150,8 +1176,7 @@ class ChartWidget extends StatelessWidget {
|
||||
child: Wrap(
|
||||
spacing: 12,
|
||||
runSpacing: 8,
|
||||
children:
|
||||
groupByValues.map((group) {
|
||||
children: groupByValues.map((group) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@ -1185,8 +1210,7 @@ class ChartWidget extends StatelessWidget {
|
||||
// }
|
||||
|
||||
// Extract all years from the chart data
|
||||
List<int> years =
|
||||
(chartData['response'] as List<dynamic>)
|
||||
List<int> years = (chartData['response'] as List<dynamic>)
|
||||
.map<int>(
|
||||
(entry) =>
|
||||
int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
|
||||
@ -1212,13 +1236,11 @@ class ChartWidget extends StatelessWidget {
|
||||
// Filter chart data to include only the selected years
|
||||
List<dynamic> filteredData =
|
||||
(chartData['response'] as List<dynamic>).where((entry) {
|
||||
int year =
|
||||
int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
|
||||
int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
|
||||
return selectedYears.contains(year);
|
||||
}).toList();
|
||||
|
||||
Set<double> uniqueXValues =
|
||||
filteredData
|
||||
Set<double> uniqueXValues = filteredData
|
||||
.map<double>(
|
||||
(entry) => double.parse(entry['ObsKey']['TIME_PERIOD']),
|
||||
)
|
||||
@ -1296,8 +1318,7 @@ class ChartWidget extends StatelessWidget {
|
||||
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
|
||||
padding: const EdgeInsets.only(right: 40, top: 10),
|
||||
child: SizedBox(
|
||||
width:
|
||||
(uniqueXValues.length * 50) +
|
||||
width: (uniqueXValues.length * 50) +
|
||||
50, // Adjust width dynamically
|
||||
child: LineChart(
|
||||
LineChartData(
|
||||
@ -1318,8 +1339,7 @@ class ChartWidget extends StatelessWidget {
|
||||
child: Wrap(
|
||||
spacing: 12,
|
||||
runSpacing: 8,
|
||||
children:
|
||||
groupByValues.map((group) {
|
||||
children: groupByValues.map((group) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@ -1359,8 +1379,7 @@ class ChartWidget extends StatelessWidget {
|
||||
// }
|
||||
|
||||
// Extract all years from the chart data
|
||||
List<int> years =
|
||||
(chartData['response'] as List<dynamic>)
|
||||
List<int> years = (chartData['response'] as List<dynamic>)
|
||||
.map<int>(
|
||||
(entry) =>
|
||||
int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
|
||||
@ -1386,13 +1405,11 @@ class ChartWidget extends StatelessWidget {
|
||||
// Filter chart data to include only the selected years
|
||||
List<dynamic> filteredData =
|
||||
(chartData['response'] as List<dynamic>).where((entry) {
|
||||
int year =
|
||||
int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
|
||||
int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
|
||||
return selectedYears.contains(year);
|
||||
}).toList();
|
||||
|
||||
Set<double> uniqueXValues =
|
||||
filteredData
|
||||
Set<double> uniqueXValues = filteredData
|
||||
.map<double>(
|
||||
(entry) => double.parse(entry['ObsKey']['TIME_PERIOD']),
|
||||
)
|
||||
@ -1456,8 +1473,7 @@ class ChartWidget extends StatelessWidget {
|
||||
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
|
||||
padding: const EdgeInsets.only(right: 40, top: 20),
|
||||
child: SizedBox(
|
||||
width:
|
||||
(uniqueXValues.length * 50) +
|
||||
width: (uniqueXValues.length * 50) +
|
||||
50, // Adjust width dynamically
|
||||
child: LineChart(
|
||||
LineChartData(
|
||||
@ -1516,13 +1532,11 @@ class ChartWidget extends StatelessWidget {
|
||||
int.tryParse(b['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
|
||||
|
||||
// Extract QUARTER and convert "Q1", "Q2", etc. to numeric values
|
||||
int quarterA =
|
||||
int.tryParse(
|
||||
int quarterA = int.tryParse(
|
||||
a['ObsKey']['QUARTER'].toString().replaceAll('Q', ''),
|
||||
) ??
|
||||
0;
|
||||
int quarterB =
|
||||
int.tryParse(
|
||||
int quarterB = int.tryParse(
|
||||
b['ObsKey']['QUARTER'].toString().replaceAll('Q', ''),
|
||||
) ??
|
||||
0;
|
||||
@ -1536,22 +1550,44 @@ class ChartWidget extends StatelessWidget {
|
||||
});
|
||||
}
|
||||
|
||||
print('chartData response sort: ${chartData['response']}');
|
||||
|
||||
// if (xValue != null && yValue != null) {
|
||||
// xAxisData.add(xValue.toString());
|
||||
// yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
|
||||
// }
|
||||
if (xValue != null && yValue != null) {
|
||||
// Check if additional_x_group is "Timeperiod" and concatenate
|
||||
// if (xValue != null && yValue != null) {
|
||||
// // Check if additional_x_group is "Timeperiod" and concatenate
|
||||
// String xLabel = xValue.toString();
|
||||
// if (xadditionalgroup == 'TIME_PERIOD' && xTimePeriod != null) {
|
||||
// xLabel = '$xTimePeriod-$xValue'; // Format: Label (TimePeriod)
|
||||
// }
|
||||
//
|
||||
// xAxisData.add(xLabel);
|
||||
// yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
|
||||
// // yAxisLabels.add(unitMsr ?? '');
|
||||
// }
|
||||
}
|
||||
for (var entry in chartData['response']) {
|
||||
var xValue = entry['ObsKey'][groupByKey];
|
||||
var xTimePeriod = entry['ObsKey']['TIME_PERIOD'];
|
||||
var yValue = entry['ObsValue']['Value'];
|
||||
var xadditionalgroup =
|
||||
chartData['chart_type_json']['additional_x_group'];
|
||||
|
||||
if (xValue != null) {
|
||||
String xLabel = xValue.toString();
|
||||
if (xadditionalgroup == 'TIME_PERIOD' && xTimePeriod != null) {
|
||||
xLabel = '$xTimePeriod-$xValue'; // Format: Label (TimePeriod)
|
||||
}
|
||||
|
||||
xAxisData.add(xLabel);
|
||||
}
|
||||
if (yValue != null) {
|
||||
yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
|
||||
// yAxisLabels.add(unitMsr ?? '');
|
||||
}
|
||||
}
|
||||
print('xAxisData $xAxisData');
|
||||
print('yAxisData $yAxisData');
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
@ -1581,21 +1617,18 @@ class ChartWidget extends StatelessWidget {
|
||||
constraints: BoxConstraints(
|
||||
minWidth:
|
||||
screenWidth, // Ensure it at least fills available width
|
||||
maxWidth:
|
||||
chartWidth > screenWidth
|
||||
maxWidth: chartWidth > screenWidth
|
||||
? chartWidth
|
||||
: screenWidth, // Prevent non-normalized constraints
|
||||
),
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width:
|
||||
xAxisData.length *
|
||||
width: xAxisData.length *
|
||||
(40 + 10), // Bar width + manual spacing
|
||||
child: BarChart(
|
||||
BarChartData(
|
||||
alignment: BarChartAlignment.spaceAround,
|
||||
maxY:
|
||||
yAxisData.isNotEmpty
|
||||
maxY: yAxisData.isNotEmpty
|
||||
? yAxisData.reduce(
|
||||
(a, b) => a > b ? a : b,
|
||||
) *
|
||||
@ -1625,8 +1658,8 @@ class ChartWidget extends StatelessWidget {
|
||||
enabled: false,
|
||||
handleBuiltInTouches: false,
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
getTooltipColor:
|
||||
(group) => Colors.transparent,
|
||||
getTooltipColor: (group) =>
|
||||
Colors.transparent,
|
||||
// fitInsideHorizontally: true,
|
||||
// fitInsideVertically: true,
|
||||
// tooltipPadding: const EdgeInsets.all(8),
|
||||
@ -1666,8 +1699,7 @@ class ChartWidget extends StatelessWidget {
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
interval:
|
||||
(yAxisData.isNotEmpty
|
||||
interval: (yAxisData.isNotEmpty
|
||||
? yAxisData.reduce(
|
||||
(a, b) => a > b ? a : b,
|
||||
) /
|
||||
@ -1691,10 +1723,12 @@ class ChartWidget extends StatelessWidget {
|
||||
getTitlesWidget: (value, meta) {
|
||||
if (value.toInt() < xAxisData.length) {
|
||||
String title = xAxisData[value.toInt()];
|
||||
String displayTitle =
|
||||
title.length > 10
|
||||
String displayTitle = title.length > 10
|
||||
? title.substring(0, 10) + '...'
|
||||
: title;
|
||||
print('barChartVALUECHECKTITLE $title');
|
||||
print(
|
||||
'barChartVALUECHECK $displayTitle');
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
@ -1711,9 +1745,8 @@ class ChartWidget extends StatelessWidget {
|
||||
child: TooltipTheme(
|
||||
data: TooltipThemeData(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Colors
|
||||
.blueGrey[800], // Change background color
|
||||
color: Colors.blueGrey[
|
||||
800], // Change background color
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
8,
|
||||
@ -1726,8 +1759,7 @@ class ChartWidget extends StatelessWidget {
|
||||
child: TooltipTheme(
|
||||
data: TooltipThemeData(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Colors
|
||||
color: Colors
|
||||
.black, // Change background color
|
||||
// color: Colors.blueGrey[800], // Change background color
|
||||
borderRadius:
|
||||
@ -1844,8 +1876,7 @@ class ChartWidget extends StatelessWidget {
|
||||
});
|
||||
|
||||
// If no valid TIME_PERIOD with a month is found, return original response
|
||||
List<Map<String, dynamic>> finalData =
|
||||
sortedData.isNotEmpty
|
||||
List<Map<String, dynamic>> finalData = sortedData.isNotEmpty
|
||||
? sortedData
|
||||
: List.from(chartData['response']);
|
||||
|
||||
@ -1926,8 +1957,7 @@ class ChartWidget extends StatelessWidget {
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
interval:
|
||||
(yAxisData.isNotEmpty
|
||||
interval: (yAxisData.isNotEmpty
|
||||
? yAxisData.reduce((a, b) => a > b ? a : b) / 5
|
||||
: 1),
|
||||
getTitlesWidget: (value, meta) {
|
||||
@ -1994,8 +2024,7 @@ class ChartWidget extends StatelessWidget {
|
||||
barsSpace: 20,
|
||||
barRods: [
|
||||
BarChartRodData(
|
||||
toY:
|
||||
(yAxisData[index] == 0)
|
||||
toY: (yAxisData[index] == 0)
|
||||
? 0.0001
|
||||
: yAxisData[index],
|
||||
// color: Colors.blueAccent,
|
||||
@ -2132,8 +2161,7 @@ class ChartWidget extends StatelessWidget {
|
||||
), // Dynamically calculate max Y
|
||||
// barGroups: _buildHorizontalRotateBarGroups(
|
||||
// chartData, groupByValues), // Build bar groups
|
||||
barGroups:
|
||||
hasBarColors
|
||||
barGroups: hasBarColors
|
||||
? _buildHorizontalRotateBarGroupsBarColors(
|
||||
chartData,
|
||||
groupByValues,
|
||||
@ -2159,8 +2187,7 @@ class ChartWidget extends StatelessWidget {
|
||||
value.toInt(),
|
||||
);
|
||||
|
||||
String displayTitle =
|
||||
title.length > 10
|
||||
String displayTitle = title.length > 10
|
||||
? title.substring(0, 10) + '...'
|
||||
: title;
|
||||
|
||||
@ -2177,8 +2204,7 @@ class ChartWidget extends StatelessWidget {
|
||||
child: TooltipTheme(
|
||||
data: TooltipThemeData(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Colors
|
||||
color: Colors
|
||||
.black, // Change background color
|
||||
// color: Colors.blueGrey[800], // Change background color
|
||||
borderRadius:
|
||||
@ -2273,8 +2299,7 @@ class ChartWidget extends StatelessWidget {
|
||||
'Crop is null or index out of bounds for cropType: $cropType and rodIndex: $rodIndex',
|
||||
);
|
||||
// crop = cropType; // Fallback to cropType
|
||||
crop =
|
||||
(crops != null && crops.isNotEmpty)
|
||||
crop = (crops != null && crops.isNotEmpty)
|
||||
? crops.first
|
||||
: cropType;
|
||||
}
|
||||
@ -2331,8 +2356,8 @@ class ChartWidget extends StatelessWidget {
|
||||
);
|
||||
|
||||
case 'horizontal_rotate':
|
||||
String cropKey =
|
||||
chartData['chart_type_json']['y_sub_group']; // Dynamically get crop key
|
||||
String cropKey = chartData['chart_type_json']
|
||||
['y_sub_group']; // Dynamically get crop key
|
||||
// Group crops by CROP_TYPE
|
||||
Map<String, List<String>> groupedCrops = {};
|
||||
|
||||
@ -2551,9 +2576,7 @@ class ChartWidget extends StatelessWidget {
|
||||
enabled: false, // Enable touch to show tooltip
|
||||
handleBuiltInTouches: false,
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
getTooltipColor:
|
||||
(group) =>
|
||||
Colors
|
||||
getTooltipColor: (group) => Colors
|
||||
.transparent, // Light background for visibility
|
||||
tooltipHorizontalAlignment:
|
||||
FLHorizontalAlignment.center,
|
||||
@ -2574,6 +2597,18 @@ class ChartWidget extends StatelessWidget {
|
||||
String crop = groupedCrops[cropType]![rodIndex];
|
||||
double value = rod.toY;
|
||||
|
||||
// Show tooltip for zero values
|
||||
if (value == 0) {
|
||||
return BarTooltipItem(
|
||||
'0', // Display "0" instead of hiding
|
||||
textAlign: TextAlign.right,
|
||||
const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 12,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Format values dynamically
|
||||
// String formattedValue = value >= 1e6
|
||||
// ? '${(value / 1e6).toStringAsFixed(1)}M'
|
||||
@ -2593,7 +2628,7 @@ class ChartWidget extends StatelessWidget {
|
||||
0,
|
||||
); // for values smaller than 1000
|
||||
}
|
||||
|
||||
print('formattedValue00 $formattedValue');
|
||||
return BarTooltipItem(
|
||||
formattedValue,
|
||||
textAlign: TextAlign.right,
|
||||
@ -2690,8 +2725,7 @@ class ChartWidget extends StatelessWidget {
|
||||
|
||||
// barGroups: _buildHorizontalRotateBarGroups(
|
||||
// chartData, groupByValues),
|
||||
barGroups:
|
||||
hasBarColors
|
||||
barGroups: hasBarColors
|
||||
? _buildHorizontalRotateBarGroupsBarColors(
|
||||
chartData,
|
||||
groupByValues,
|
||||
@ -2923,8 +2957,7 @@ class ChartWidget extends StatelessWidget {
|
||||
// return FlSpot(xValue, yValue);
|
||||
// }).toList();
|
||||
|
||||
List<FlSpot> spots =
|
||||
filteredData
|
||||
List<FlSpot> spots = filteredData
|
||||
.where((entry) => entry['ObsKey'][groupByKey] == group)
|
||||
.map<FlSpot>((entry) {
|
||||
String timePeriod = entry['ObsKey']['TIME_PERIOD'];
|
||||
@ -2946,8 +2979,7 @@ class ChartWidget extends StatelessWidget {
|
||||
yValue = value;
|
||||
} else if (value is String) {
|
||||
yValue =
|
||||
double.tryParse(value) ??
|
||||
0.0; // Handle invalid strings safely
|
||||
double.tryParse(value) ?? 0.0; // Handle invalid strings safely
|
||||
} else {
|
||||
throw Exception(
|
||||
"Unexpected value type: ${value.runtimeType}",
|
||||
@ -2956,8 +2988,7 @@ class ChartWidget extends StatelessWidget {
|
||||
print('LineTrendX $xValue');
|
||||
print('LineTrendY $yValue');
|
||||
return FlSpot(xValue, yValue);
|
||||
})
|
||||
.toList()
|
||||
}).toList()
|
||||
..sort((a, b) => a.x.compareTo(b.x));
|
||||
|
||||
print('spots - $spots');
|
||||
@ -3014,8 +3045,7 @@ class ChartWidget extends StatelessWidget {
|
||||
getTooltipColor: (spot) => Colors.black,
|
||||
getTooltipItems: (List<LineBarSpot> lineBarsSpot) {
|
||||
return lineBarsSpot.map((lineBarSpot) {
|
||||
Color lineColor =
|
||||
lineBarSpot.bar is LineChartBarData
|
||||
Color lineColor = lineBarSpot.bar is LineChartBarData
|
||||
? (lineBarSpot.bar).color ?? Colors.white
|
||||
: Colors.white; // Extract bar color safely
|
||||
return LineTooltipItem(
|
||||
@ -3030,8 +3060,7 @@ class ChartWidget extends StatelessWidget {
|
||||
),
|
||||
TextSpan(
|
||||
// text: formatNumber(lineBarSpot.y),
|
||||
text:
|
||||
(chartConversion != null &&
|
||||
text: (chartConversion != null &&
|
||||
chartConversion.isNotEmpty &&
|
||||
number_format != null)
|
||||
? formatNumberConversion(
|
||||
@ -3128,10 +3157,10 @@ class ChartWidget extends StatelessWidget {
|
||||
return FlGridData(
|
||||
show: false,
|
||||
drawVerticalLine: true,
|
||||
getDrawingHorizontalLine:
|
||||
(value) => FlLine(color: Colors.grey, strokeWidth: 1),
|
||||
getDrawingVerticalLine:
|
||||
(value) => FlLine(color: Colors.grey, strokeWidth: 1),
|
||||
getDrawingHorizontalLine: (value) =>
|
||||
FlLine(color: Colors.grey, strokeWidth: 1),
|
||||
getDrawingVerticalLine: (value) =>
|
||||
FlLine(color: Colors.grey, strokeWidth: 1),
|
||||
);
|
||||
}
|
||||
|
||||
@ -3568,18 +3597,16 @@ class ChartWidget extends StatelessWidget {
|
||||
String groupValue = groupByValues.elementAt(i);
|
||||
|
||||
// Filter data for the current group (grouping by CROP_TYPE)
|
||||
List<dynamic> groupData =
|
||||
responseData.where((entry) {
|
||||
List<dynamic> groupData = responseData.where((entry) {
|
||||
return entry['ObsKey'][groupByKeyValueData] == groupValue;
|
||||
}).toList();
|
||||
|
||||
// Create BarChartRodData for each bar in the group
|
||||
List<BarChartRodData> barRods =
|
||||
groupData.map((data) {
|
||||
List<BarChartRodData> barRods = groupData.map((data) {
|
||||
// Ensure to retrieve and parse 'ObsValue' value (which should be a double)
|
||||
double value =
|
||||
double.tryParse(data['ObsValue']['Value'].toString()) ?? 0.0;
|
||||
// double minBarHeight = 0.5;
|
||||
double minBarHeight = 0.1;
|
||||
print('multi_bar1.1');
|
||||
// final List<Color> uniqueColorsForTwo = [
|
||||
// Color(0xFF648CBA),
|
||||
@ -3598,13 +3625,11 @@ class ChartWidget extends StatelessWidget {
|
||||
chartData['dataset'] == 'hotel_guests' ||
|
||||
chartData['dataset'] == 'health_services' ||
|
||||
chartData['dataset'] == 'clinics') {
|
||||
barColor =
|
||||
uniqueColorsForTwo[colorIndex % uniqueColorsForTwo.length];
|
||||
barColor = uniqueColorsForTwo[colorIndex % uniqueColorsForTwo.length];
|
||||
colorIndex++;
|
||||
} else if (chartData['dataset'] == 'cropsk') {
|
||||
barColor =
|
||||
uniqueColorsForThree[colorIndex %
|
||||
uniqueColorsForThree.length];
|
||||
uniqueColorsForThree[colorIndex % uniqueColorsForThree.length];
|
||||
colorIndex++;
|
||||
} else if (chartData['dataset'] == 'oil_and_gas') {
|
||||
barColor =
|
||||
@ -3616,7 +3641,8 @@ class ChartWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
return BarChartRodData(
|
||||
toY: value, // Use the parsed value
|
||||
// toY: value,
|
||||
toY: value == 0 ? minBarHeight : value, // Use the parsed value
|
||||
color: barColor, // Dynamic color
|
||||
width: 20,
|
||||
|
||||
@ -3677,8 +3703,7 @@ class ChartWidget extends StatelessWidget {
|
||||
String groupValue = groupByValues.elementAt(i);
|
||||
|
||||
// Filter data for the current group
|
||||
List<dynamic> groupData =
|
||||
responseData.where((entry) {
|
||||
List<dynamic> groupData = responseData.where((entry) {
|
||||
return entry['ObsKey'][groupByKeyValueData1] == groupValue;
|
||||
}).toList();
|
||||
|
||||
@ -3698,8 +3723,7 @@ class ChartWidget extends StatelessWidget {
|
||||
});
|
||||
|
||||
// Create BarChartRodData for each bar in the group
|
||||
List<BarChartRodData> barRods =
|
||||
groupData.map((data) {
|
||||
List<BarChartRodData> barRods = groupData.map((data) {
|
||||
double value =
|
||||
double.tryParse(data['ObsValue']['Value'].toString()) ?? 0.0;
|
||||
|
||||
@ -3714,9 +3738,8 @@ class ChartWidget extends StatelessWidget {
|
||||
// Determine color dynamically
|
||||
Color barColor;
|
||||
if (chartData['dataset'] == 'health_services') {
|
||||
barColor =
|
||||
uniqueColorsForTwo[colorIndex %
|
||||
2]; // Alternate between two colors
|
||||
barColor = uniqueColorsForTwo[
|
||||
colorIndex % 2]; // Alternate between two colors
|
||||
colorIndex++; // Update index for next bar
|
||||
} else {
|
||||
// barColor = chartBarColors[gender] ?? Colors.grey; // Default gender-based color
|
||||
@ -3772,14 +3795,12 @@ Widget _buildChartLegend(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 12,
|
||||
runSpacing: 6,
|
||||
children:
|
||||
uniqueCropTypes.map((cropType) {
|
||||
children: uniqueCropTypes.map((cropType) {
|
||||
// Color cropColor = parsedChartBarColors[cropType] ?? Colors.grey; // Fetch color for each crop type
|
||||
int index = uniqueCropTypes.toList().indexOf(
|
||||
cropType,
|
||||
); // Get index for cycling colors
|
||||
Color cropColor =
|
||||
parsedChartBarColors.isNotEmpty &&
|
||||
Color cropColor = parsedChartBarColors.isNotEmpty &&
|
||||
parsedChartBarColors.containsKey(cropType)
|
||||
? parsedChartBarColors[cropType]!
|
||||
: uniqueColors[index % uniqueColors.length];
|
||||
|
||||
@ -702,6 +702,8 @@ class LoginRoute extends HookConsumerWidget {
|
||||
);
|
||||
final dontHaveAnAccountRegisterBtn = TextButton(
|
||||
onPressed: () => {context.push('/register')},
|
||||
// onPressed: () =>
|
||||
// {context.push('/forgot-password/surendar.m@venbainfotech.com')},
|
||||
child: Text.rich(
|
||||
textAlign: TextAlign.center,
|
||||
TextSpan(
|
||||
|
||||
@ -152,7 +152,9 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
|
||||
isLoading = false;
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(AppLocalizations.of(context)!.status_success),),
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.status_success),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
@ -160,13 +162,16 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(context.translate('Error updating status: $e','$e خطأ في تحديث الحالة: '))),
|
||||
SnackBar(
|
||||
content: Text(context.translate(
|
||||
'Error updating status: $e', '$e خطأ في تحديث الحالة: '))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//Method to show a confirmation dialog when status is changed
|
||||
Future<void> _showConfirmationDialog(User user, String newStatus,String statusUpdate) async {
|
||||
Future<void> _showConfirmationDialog(
|
||||
User user, String newStatus, String statusUpdate) async {
|
||||
print('user $user');
|
||||
double myheight = MediaQuery.of(context).size.height;
|
||||
|
||||
@ -416,8 +421,9 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
|
||||
// // fit: BoxFit.contain,
|
||||
// ),
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 9, horizontal: 18.0),
|
||||
// contentPadding: EdgeInsets.symmetric(
|
||||
// vertical: 9, horizontal: 18.0),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
onChanged: filterUsers,
|
||||
),
|
||||
@ -444,7 +450,8 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
|
||||
SizedBox(height: 15),
|
||||
// Space between icon and text
|
||||
Text(
|
||||
AppLocalizations.of(context)!.no_result_found,
|
||||
AppLocalizations.of(context)!
|
||||
.no_result_found,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -455,7 +462,9 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
|
||||
SizedBox(height: 12), // Space between texts
|
||||
FittedBox(
|
||||
child: Text(
|
||||
context.translate("We couldn't find anything matching your search.",'لم نعثر على أي شيء يطابق بحثك.'),
|
||||
context.translate(
|
||||
"We couldn't find anything matching your search.",
|
||||
'لم نعثر على أي شيء يطابق بحثك.'),
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: Color(0xFF898C81)),
|
||||
@ -533,7 +542,9 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
|
||||
(index) => DataCell(
|
||||
index == 0
|
||||
? Text(
|
||||
AppLocalizations.of(context)!.no_result_found,
|
||||
AppLocalizations.of(
|
||||
context)!
|
||||
.no_result_found,
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle
|
||||
.italic),
|
||||
@ -573,7 +584,11 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
|
||||
print(user);
|
||||
if (newStatus != null) {
|
||||
_showConfirmationDialog(
|
||||
user, newStatus, statusOptions[newStatus]!,);
|
||||
user,
|
||||
newStatus,
|
||||
statusOptions[
|
||||
newStatus]!,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@ -298,7 +298,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
createTargetContent(
|
||||
text: AppLocalizations.of(context)!.mainMenu,
|
||||
alignment: ContentAlign.bottom,
|
||||
space:55,
|
||||
space: 55,
|
||||
gap: 55,
|
||||
),
|
||||
TargetContent(
|
||||
@ -989,7 +989,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.mail_outlined),
|
||||
title: Text(context.translate('Contact Us', 'اتصل بنا'),),
|
||||
title: Text(
|
||||
context.translate('Contact Us', 'اتصل بنا'),
|
||||
),
|
||||
onTap: () => context.push('/contact'),
|
||||
),
|
||||
if (userId != 'guest')
|
||||
|
||||
@ -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.42+43
|
||||
version: 1.0.43+44
|
||||
|
||||
environment:
|
||||
sdk: ">=3.2.3 <4.0.0"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user