Updated UI for logout confirmation popup

This commit is contained in:
Juki-shiba 2025-02-20 18:18:40 +05:30
commit 95a803269b
22 changed files with 1692 additions and 1024 deletions

View File

@ -15,12 +15,12 @@ if (localPropertiesFile.exists()) {
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
flutterVersionCode = "20"
flutterVersionCode = "24"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
flutterVersionName = "1.0.19"
flutterVersionName = "1.0.23"
}
def keystorePropertiesFile = rootProject.file("key.properties")

View File

@ -39,7 +39,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
String? _validateOldPassword(String? value) {
if (value == null || value.isEmpty) {
return 'Old password is required';
return AppLocalizations.of(context)!.old_password_is_required;
}
return null;
}
@ -56,37 +56,38 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
final hasSpecialCharacter = RegExp(r'[~!@#$%^&*()_+=[\]{}|;:,.<>?/-]');
if (value == null || value.isEmpty) {
return 'New password is required';
return AppLocalizations.of(context)!.new_password_required;
} else if (value.length < 8 || value.length > 64) {
return 'Password must be between 8 and 64 characters';
return AppLocalizations.of(context)!.password_between_8_to_40;
} else if (value == _oldPassword) {
return 'New password must not be the same as the old password';
// return 'New password must not be the same as the old password';
return AppLocalizations.of(context)!.new_password_not_same_as_old;
}
// Check the regular expression for allowed characters
if (!regex.hasMatch(value)) {
return 'Password contains invalid characters';
return AppLocalizations.of(context)!.password_invalid;
}
// Track missing constraints
List<String> missingConstraints = [];
if (!hasUppercase.hasMatch(value)) {
missingConstraints.add('uppercase letter');
missingConstraints.add(context.translate('uppercase letter','حرف كبير'));
}
if (!hasLowercase.hasMatch(value)) {
missingConstraints.add('lowercase letter');
missingConstraints.add(context.translate('lowercase letter','حرف صغير'));
}
if (!hasDigit.hasMatch(value)) {
missingConstraints.add('numeric digit');
missingConstraints.add(context.translate('numeric digit','رقم'));
}
if (!hasSpecialCharacter.hasMatch(value)) {
missingConstraints.add('special character');
missingConstraints.add(context.translate('special character','رمز خاص'));
}
// If there are missing constraints, return a consolidated message
if (missingConstraints.isNotEmpty) {
return 'At least one ${missingConstraints.join(', ')}';
return context.translate('At least one ${missingConstraints.join(', ')}','${missingConstraints.join(', ')}على الأقل واحد ');
}
_newPassword = value; // Store for validation
@ -95,9 +96,10 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
String? _validateConfirmPassword(String? value) {
if (value == null || value.isEmpty) {
return 'Confirm password is required';
return AppLocalizations.of(context)!.confirm_new_password;
} else if (value != _newPassword) {
return 'Passwords do not match';
// return 'Passwords do not match';
return AppLocalizations.of(context)!.password_match;
}
_confirmPassword = value;
return null;
@ -151,7 +153,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Password updated successfully.'),
content: Text(AppLocalizations.of(context)!.password_update_successfully),
backgroundColor: Colors.green,
),
);
@ -171,7 +173,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Your old password is incorrect.'),
content: Text(AppLocalizations.of(context)!.your_old_password_incorrect),
backgroundColor: Colors.red,
),
);
@ -191,7 +193,6 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
final passwordLocale = ref.watch(localeProvider);
return Scaffold(
backgroundColor: Colors.white,

View File

@ -1,10 +1,16 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
class PrivacyPolicy extends StatelessWidget {
const PrivacyPolicy({super.key});
PrivacyPolicy({super.key});
final fcscBanner = Image.asset(
BannerAssetPath.fcsc,
height: 40,
alignment: Alignment.center,
);
@override
Widget build(BuildContext context) {
return Theme(
@ -17,6 +23,12 @@ class PrivacyPolicy extends StatelessWidget {
),
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios_new,size: 24,),
onPressed: (){
context.pop();
},
),
scrolledUnderElevation: 0,
title:Text(context.translate(
'Privacy Policy',
@ -872,7 +884,8 @@ class PrivacyPolicy extends StatelessWidget {
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
),
SizedBox(height: 20),
Center(child: fcscBanner),
SizedBox(height: 20),
],
)
),

View File

@ -1,9 +1,16 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
class TermsOfUse extends StatelessWidget {
const TermsOfUse({super.key});
TermsOfUse({super.key});
final fcscBanner = Image.asset(
BannerAssetPath.fcsc,
height: 40,
alignment: Alignment.center,
);
@override
Widget build(BuildContext context) {
@ -17,6 +24,12 @@ class TermsOfUse extends StatelessWidget {
),
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios_new,size: 24,),
onPressed: (){
context.pop();
},
),
scrolledUnderElevation: 0,
title:Text(context.translate(
'Terms & Conditions',
@ -699,6 +712,8 @@ class TermsOfUse extends StatelessWidget {
),
),
SizedBox(height: 10),
Center(child: fcscBanner),
SizedBox(height: 20),
],
),
),

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
@ -48,27 +49,78 @@ class ChartWidget extends StatelessWidget {
List<PieChartSectionData> parsePieChartData(
dynamic chartData,
double totalValue,
// String totalValue,
int? touchedIndex,
) {
debugPrint('Chart Data: ${jsonEncode(chartData)}');
return chartData['response']
.asMap()
.entries
.map<PieChartSectionData>((entry) {
int index = entry.key;
print('piePArse');
var data = entry.value;
double value = double.tryParse(data['ObsValue']['Value']) ?? 0.0;
double percentage = (value / totalValue) * 100;
// double value = double.tryParse(data['ObsValue']['Value']) ?? 0.0;
// double value = (data['ObsValue']['Value'] is double)
// ? data['ObsValue']['Value']
// : (data['ObsValue']['Value'] is int)
// ? (data['ObsValue']['Value'] as int).toDouble()
// : 0.0;
// Handle different types: int, double, and String
double value = 0.0;
var rawValue = data['ObsValue']['Value'];
print('Raw Value: $rawValue (Type: ${rawValue.runtimeType})');
if (rawValue is String) {
value = double.tryParse(rawValue) ?? 0.0;
} else if (rawValue is int) {
value = rawValue.toDouble();
} else if (rawValue is double) {
value = rawValue;
} else {
print('Unexpected Type for ObsValue[Value]: ${rawValue.runtimeType}');
}
// if (data['ObsValue']['Value'] is String) {
// value = double.tryParse(data['ObsValue']['Value']) ?? 0.0; // Parse string to double
// } else if (data['ObsValue']['Value'] is int) {
// value = (data['ObsValue']['Value'] as int).toDouble(); // Convert int to double
// } else if (data['ObsValue']['Value'] is double) {
// value = data['ObsValue']['Value']; // Already a double
// }
print('piePArse1 - $value');
// double percentage = (value / totalValue) * 100;
double percentage = (totalValue > 0) ? (value / totalValue) * 100 : 0.0;
if (kDebugMode) {
print('percentage- $percentage');
print('Total Value: $totalValue');
}
debugPrint('debug Total Value- $totalValue');
debugPrint('debug percentage- $percentage');
bool isTouched = index == touchedIndex;
return PieChartSectionData(
value: value,
color: Colors.primaries[index % Colors.primaries.length],
title: '${percentage.toStringAsFixed(1)}%',
radius: isTouched ? 60 : 50, // Increase size when touched
radius: isTouched ? 60 : 50,
// Increase size when touched
titleStyle: TextStyle(
fontSize: isTouched ? 12 : 10,
fontWeight: FontWeight.bold,
color: Colors.white,
color: Colors.black,
// color: Colors.white,
),
titlePositionPercentageOffset: 1.3,
);
}).toList();
}
@ -94,14 +146,34 @@ class ChartWidget extends StatelessWidget {
),
),
SizedBox(width: 8),
Tooltip(
TooltipTheme(
data: TooltipThemeData(
decoration: BoxDecoration(
color: Colors.blueGrey[800], // Change background color
borderRadius:
BorderRadius.circular(8), // Optional: rounded corners
),
textStyle: TextStyle(color: Colors.white), // Change text color
),
child: Tooltip(
message: title, // Full text on hover
child: ConstrainedBox(
// Constrain width to allow wrapping
constraints: BoxConstraints(maxWidth: 100),
child: Text(
shortTitle,
style: TextStyle(fontSize: 12),
overflow: TextOverflow.ellipsis, // Ensures text doesn't overflow
title,
style: TextStyle(
fontSize: 12,
),
softWrap: true,
maxLines: 2,
overflow:
TextOverflow.ellipsis, // Ensures text doesn't overflow
),
),
),
),
SizedBox(width: 5),
],
);
}).toList();
@ -123,6 +195,8 @@ class ChartWidget extends StatelessWidget {
return Center(child: Text('No chart data available'));
}
print(chartData['chart_type_json']['TIME_PERIOD']);
String groupByKey = chartData['group_by'] ?? '';
print('groupByKey $groupByKey');
Set<String> groupByValues = extractGroupByValues(chartData, groupByKey);
@ -213,10 +287,28 @@ class ChartWidget extends StatelessWidget {
),
);
case 'pie_chart':
double totalValue = chartData['response']
.map<double>(
(entry) => double.tryParse(entry['ObsValue']['Value']) ?? 0.0)
.fold(0.0, (prev, element) => prev + element);
double totalValue = chartData['response'].map<double>((entry) {
var value = entry['ObsValue']['Value'];
print(
'Processing value: $value, type: ${value.runtimeType}'); // Debug each value
print(value is int
? value.toDouble()
: value is String
? double.tryParse(value) ?? 0.0
: 0.0);
return (value is num)
? value.toDouble()
: value is String
? double.tryParse(value) ?? 0.0
: 0.0;
}).fold(0.0, (prev, element) => prev + element);
// List<String> totalValues = chartData['response']
// .map<String>((entry) {
// var value = entry['ObsValue']['Value'];
// print('Processing value: $value, type: ${value.runtimeType}'); // Debug each value
//
// return value.toString(); // Convert to string
// }).fold(0.0, (prev, element) => prev + element);
ValueNotifier<int?> touchedIndex = ValueNotifier(null);
@ -231,7 +323,7 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
SizedBox(height: 15),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
@ -240,7 +332,7 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 20),
SizedBox(height: 70),
Expanded(
child: ValueListenableBuilder<int?>(
valueListenable: touchedIndex,
@ -269,16 +361,19 @@ class ChartWidget extends StatelessWidget {
},
),
),
SizedBox(height: 25),
SizedBox(height: 65),
Flexible(
// child: SingleChildScrollView(
// scrollDirection: Axis.horizontal,
//
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
constraints:
BoxConstraints(minHeight: 5), // Allow dynamic height
BoxConstraints(minHeight: 3), // Allow dynamic height
child: Padding(
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, bottom: 8.0, top: 20.0),
left: 0.0, right: 0.0, bottom: 8.0, top: 20.0),
child: Wrap(
spacing: 12,
runSpacing: 8,
@ -288,6 +383,8 @@ class ChartWidget extends StatelessWidget {
),
),
),
// ),
),
],
);
@ -325,7 +422,7 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
SizedBox(height: 15),
AspectRatio(
aspectRatio: 1.5,
child: BarChart(
@ -336,8 +433,12 @@ class ChartWidget extends StatelessWidget {
// tooltipBgColor: Colors.black.withOpacity(0.8),
fitInsideHorizontally: true,
fitInsideVertically: true,
tooltipPadding: const EdgeInsets.all(8),
// tooltipPadding: const EdgeInsets.all(8),
tooltipPadding: const EdgeInsets.symmetric(
horizontal: 4, vertical: 8), // Optional
tooltipHorizontalAlignment: FLHorizontalAlignment.left,
tooltipMargin: 16,
getTooltipItem:
(groupData, groupIndex, rodData, rodIndex) {
// Get the list of group names dynamically
@ -395,6 +496,7 @@ class ChartWidget extends StatelessWidget {
'',
TextStyle(color: Colors.white, fontSize: 12),
children: tooltipTextSpans,
textAlign: TextAlign.left,
);
},
),
@ -458,7 +560,7 @@ class ChartWidget extends StatelessWidget {
waitDuration: Duration(milliseconds: 500),
showDuration: Duration(seconds: 2),
decoration: BoxDecoration(
color: Colors.black,
color: Colors.blueGrey[900],
borderRadius: BorderRadius.circular(4),
),
textStyle: TextStyle(color: Colors.white),
@ -531,11 +633,10 @@ class ChartWidget extends StatelessWidget {
// (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
// .toSet();
Set<String> uniqueXValues = filteredData
.map<String>((entry) {
String? timePeriod = entry['ObsKey']['TIME_PERIOD']; // Nullable String
// print('TIME_PERIOD- $timePeriod');
Set<String> uniqueXValues = filteredData.map<String>((entry) {
String? timePeriod =
entry['ObsKey']['TIME_PERIOD']; // Nullable String
print('TIME_PERIOD- $timePeriod');
if (timePeriod == null) {
print('TIME_PERIOD is null');
@ -556,8 +657,7 @@ class ChartWidget extends StatelessWidget {
print('Unknown format: $timePeriod');
return timePeriod; // Keep it as is
}
})
.toSet();
}).toSet();
print("Unique X Values: $uniqueXValues");
@ -566,18 +666,30 @@ class ChartWidget extends StatelessWidget {
if (RegExp(r'^\d{4}$').hasMatch(timePeriod)) {
return double.parse(timePeriod); // Year-only (2019 2019.0)
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
return double.parse(timePeriod.replaceAll('-', '.')); // Year-Month (2019-11 2019.11)
return double.parse(timePeriod.replaceAll(
'-', '.')); // Year-Month (2019-11 2019.11)
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
// Year-MonthAbbr (2019-Nov)
Map<String, int> monthMap = {
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
'Jan': 1,
'Feb': 2,
'Mar': 3,
'Apr': 4,
'May': 5,
'Jun': 6,
'Jul': 7,
'Aug': 8,
'Sep': 9,
'Oct': 10,
'Nov': 11,
'Dec': 12
};
List<String> parts = timePeriod.split('-');
int month = monthMap[parts[1]] ?? 1; // Default to January if unknown
return double.parse('${parts[0]}.$month'); // Convert to format (2019-Nov 2019.11)
int month =
monthMap[parts[1]] ?? 1; // Default to January if unknown
return double.parse(
'${parts[0]}.$month'); // Convert to format (2019-Nov 2019.11)
}
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
@ -589,15 +701,12 @@ class ChartWidget extends StatelessWidget {
.toSet();
print('Processed X Values: $uniqueXValuesProcessed');
print('LnTrnd2.1');
// Generate line bars for the chart
List<LineChartBarData> lineBars =
lineBarsData(filteredData, groupByValues, groupByKey);
print('LnTrnd3');
return Column(children: [
@ -631,7 +740,6 @@ class ChartWidget extends StatelessWidget {
// minX: uniqueXValues.reduce((a, b) => a < b ? a : b),
// maxX: uniqueXValues.reduce((a, b) => a > b ? a : b),
// minX: uniqueXValuesProcessed.reduce((a, b) => a < b ? a : b),
// maxX: uniqueXValuesProcessed.reduce((a, b) => a > b ? a : b),
))),
@ -859,7 +967,7 @@ class ChartWidget extends StatelessWidget {
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
padding: const EdgeInsets.only(right: 40),
padding: const EdgeInsets.only(right: 40, top: 20),
child: SizedBox(
width: (uniqueXValues.length * 50) +
50, // Adjust width dynamically
@ -884,11 +992,61 @@ class ChartWidget extends StatelessWidget {
List<String> xAxisData = [];
List<double> yAxisData = [];
var xadditionalgrp = chartData['chart_type_json']['additional_x_group'];
print('xadditionalgrp-$xadditionalgrp');
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'];
print('chartData response: ${chartData['response']}');
print('xValue-$xValue');
print('Xadditionalt-$xTimePeriod');
print('xadditionalgroup-$xadditionalgroup');
print('yValue-$yValue');
if (xadditionalgrp == 'TIME_PERIOD') {
chartData['response'].sort((a, b) {
// Convert TIME_PERIOD to int for proper sorting
int timeA =
int.tryParse(a['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
int timeB =
int.tryParse(b['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
// Extract QUARTER and convert "Q1", "Q2", etc. to numeric values
int quarterA = int.tryParse(
a['ObsKey']['QUARTER'].toString().replaceAll('Q', '')) ??
0;
int quarterB = int.tryParse(
b['ObsKey']['QUARTER'].toString().replaceAll('Q', '')) ??
0;
// First, sort by TIME_PERIOD. If equal, sort by QUARTER
if (timeA != timeB) {
return timeA.compareTo(timeB);
} else {
return quarterA.compareTo(quarterB);
}
});
}
// if (xValue != null && yValue != null) {
// xAxisData.add(xValue.toString());
// yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
// }
if (xValue != null && yValue != null) {
xAxisData.add(xValue.toString());
// 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);
}
}
@ -919,7 +1077,23 @@ class ChartWidget extends StatelessWidget {
maxY: yAxisData.isNotEmpty
? yAxisData.reduce((a, b) => a > b ? a : b) * 1.2
: 10,
barTouchData: BarTouchData(enabled: true),
// barTouchData: BarTouchData(enabled: true),
barTouchData: BarTouchData(
enabled: true,
handleBuiltInTouches: true,
touchTooltipData: BarTouchTooltipData(
// fitInsideHorizontally: true,
// fitInsideVertically: true,
// tooltipPadding: const EdgeInsets.all(8),
// tooltipMargin: 16,
getTooltipItem: (group, groupIndex, rod, rodIndex) {
return BarTooltipItem(
rod.toY.toStringAsFixed(1),
const TextStyle(color: Colors.white),
);
},
),
),
titlesData: FlTitlesData(
leftTitles: AxisTitles(
sideTitles: SideTitles(
@ -948,23 +1122,57 @@ class ChartWidget extends StatelessWidget {
: title;
return Padding(
padding: const EdgeInsets.only(top: 8.0),
padding:
const EdgeInsets.only(top: 8.0, left: 55.0),
child: SizedBox(
width: 60, // Limit width to force wrapping
child: Transform.rotate(
angle: -0.5,
// angle: -0.5,
angle: -1.5,
child: TooltipTheme(
data: TooltipThemeData(
decoration: BoxDecoration(
color: Colors.blueGrey[
800], // Change background color
borderRadius: BorderRadius.circular(
8), // Optional: rounded corners
),
textStyle: TextStyle(
color: Colors
.white), // Change text color
),
child: TooltipTheme(
data: TooltipThemeData(
decoration: BoxDecoration(
color: Colors.blueGrey[
800], // Change background color
borderRadius: BorderRadius.circular(
8), // Optional: rounded corners
),
textStyle: TextStyle(
color: Colors
.white), // Change text color
),
child: Tooltip(
message: title,
child: Text(
// title,
displayTitle,
softWrap: true,
style: TextStyle(
fontSize: 10,
),
overflow: TextOverflow.ellipsis,
)),
),
),
),
),
)));
}
return Container();
},
reservedSize: 40,
reservedSize: 80,
),
),
topTitles: AxisTitles(
@ -1087,7 +1295,7 @@ class ChartWidget extends StatelessWidget {
xAxisData[value.toInt()],
style: const TextStyle(fontSize: 12),
softWrap: true,
maxLines: 2,
maxLines: 3,
),
),
),
@ -1100,7 +1308,8 @@ class ChartWidget extends StatelessWidget {
),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false), // Hide top titles
sideTitles:
SideTitles(showTitles: false), // Hide top titles
),
rightTitles: AxisTitles(
sideTitles:
@ -1124,7 +1333,8 @@ class ChartWidget extends StatelessWidget {
),
),
),
))
),
),
]);
case 'fl_multi_bar':
double _calculateChartWidth(dynamic chartData) {
@ -1136,22 +1346,19 @@ class ChartWidget extends StatelessWidget {
// Group crops by CROP_TYPE
Map<String, List<String>> groupedCrops = {};
int touchedGroupIndex = -1;
// Iterate over the chartData to group crops by CROP_TYPE
for (var item in chartData['response']) {
// print("MultiBArRaw item: $item");
print("MultiBArRaw item: $item");
String crop = item['ObsKey'][cropKey];
String cropType = item['ObsKey'][groupByKey];
// Use a Set to avoid duplicates
if (groupedCrops.containsKey(cropType)) {
groupedCrops[cropType] = (groupedCrops[cropType]! + [crop]).toSet().toList();
groupedCrops[cropType] =
(groupedCrops[cropType]! + [crop]).toSet().toList();
} else {
groupedCrops[cropType] = [crop];
}
@ -1173,8 +1380,8 @@ class ChartWidget extends StatelessWidget {
//
// print('groupedCropsflmutli- $groupedCrops');
return Column(children: [
return Center(
child: Column(children: [
Text(
chartData['chart_heading'] ?? '', // Chart title from data
style: TextStyle(
@ -1203,8 +1410,8 @@ class ChartWidget extends StatelessWidget {
child: BarChart(
BarChartData(
alignment: BarChartAlignment.spaceAround,
maxY:
_calculateMaxY(chartData), // Dynamically calculate max Y
maxY: _calculateMaxY(
chartData), // Dynamically calculate max Y
barGroups: _buildHorizontalRotateBarGroups(
chartData, groupByValues), // Build bar groups
titlesData: FlTitlesData(
@ -1227,16 +1434,31 @@ class ChartWidget extends StatelessWidget {
return Padding(
padding: const EdgeInsets.only(top: 8.0),
child: SizedBox(
width: 60, // Limit width to force wrapping
width:
60, // Limit width to force wrapping
child: Transform.rotate(
angle: -0.5,
child: TooltipTheme(
data: TooltipThemeData(
decoration: BoxDecoration(
color: Colors.blueGrey[
800], // Change background color
borderRadius: BorderRadius.circular(
8), // Optional: rounded corners
),
textStyle: TextStyle(
color: Colors
.white), // Change text color
),
child: Tooltip(
message: title,
child: Text(
displayTitle,
softWrap: true,
// style: TextStyle(backgroundColor: Colors.blueGrey[800]),
overflow: TextOverflow.ellipsis,
)),
),
)));
// return Transform.rotate(
// angle:
@ -1259,7 +1481,8 @@ class ChartWidget extends StatelessWidget {
borderData: FlBorderData(show: false),
barTouchData: BarTouchData(
touchTooltipData: BarTouchTooltipData(
tooltipHorizontalAlignment: FLHorizontalAlignment.center,
tooltipHorizontalAlignment:
FLHorizontalAlignment.center,
tooltipRoundedRadius: 8,
fitInsideHorizontally:
true, // Ensure it fits within the screen
@ -1277,7 +1500,8 @@ class ChartWidget extends StatelessWidget {
groupByValues.elementAt(groupIndex);
// Fetch the crop for the current group from groupedCrops
String cropType = groupByValues.elementAt(groupIndex);
String cropType =
groupByValues.elementAt(groupIndex);
print('GrpcropType: $cropType');
// String crop = groupedCrops[cropType]![rodIndex];
@ -1290,7 +1514,9 @@ class ChartWidget extends StatelessWidget {
print(
'Crop is null or index out of bounds for cropType: $cropType and rodIndex: $rodIndex');
// crop = cropType; // Fallback to cropType
crop = (crops != null && crops.isNotEmpty) ? crops.first : cropType;
crop = (crops != null && crops.isNotEmpty)
? crops.first
: cropType;
}
// print('groupedCrops1: $groupedCrops - $rodIndex');
@ -1337,7 +1563,8 @@ class ChartWidget extends StatelessWidget {
response != null &&
response.spot != null) {
// setState(() {
touchedGroupIndex = response.spot!.touchedBarGroupIndex;
touchedGroupIndex =
response.spot!.touchedBarGroupIndex;
// });
} else {
// setState(() {
@ -1351,7 +1578,8 @@ class ChartWidget extends StatelessWidget {
),
),
))
]);
]),
);
case 'horizontal_rotate':
String cropKey = chartData['chart_type_json']
@ -1855,7 +2083,6 @@ class ChartWidget extends StatelessWidget {
return lineBars;
}
/// Function to parse TIME_PERIOD into a EXACT value
double parseTimePeriod(String timePeriod) {
// Match formats
@ -1864,13 +2091,23 @@ class ChartWidget extends StatelessWidget {
return double.parse(timePeriod); // Year as a double (2020 2020.0)
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
// Format: Year-Month (e.g., "2020-10")
return double.parse(timePeriod.replaceAll('-', '.')); // Convert "2020-10" 2020.10
return double.parse(
timePeriod.replaceAll('-', '.')); // Convert "2020-10" 2020.10
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
// Format: Year-MonthAbbr (e.g., "2020-Oct")
Map<String, int> monthMap = {
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
'Jan': 1,
'Feb': 2,
'Mar': 3,
'Apr': 4,
'May': 5,
'Jun': 6,
'Jul': 7,
'Aug': 8,
'Sep': 9,
'Oct': 10,
'Nov': 11,
'Dec': 12
};
List<String> parts = timePeriod.split('-');
@ -1882,7 +2119,6 @@ class ChartWidget extends StatelessWidget {
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
}
List<LineChartBarData> lineBarsData(List<dynamic> filteredData,
Set<String> groupByValues, String groupByKey) {
List<LineChartBarData> lineBars = [];
@ -1947,9 +2183,6 @@ class ChartWidget extends StatelessWidget {
print('spots - $spots');
// List<FlSpot> spots = filteredData
// .where((entry) => entry['ObsKey'][groupByKey] == group)
// .map<FlSpot>((entry) {
@ -1965,8 +2198,6 @@ class ChartWidget extends StatelessWidget {
// return FlSpot(xValue, yValue);
// }).toList();
print('lineGrp2');
// Add a line for this group
lineBars.add(
@ -2011,11 +2242,11 @@ class ChartWidget extends StatelessWidget {
}
FlTitlesData titlesData1(Set<double> xValues) {
print('tileDATa1xvalue - $xValues');
double findClosest(double value, Set<double> values) {
return values.reduce((a, b) => (value - a).abs() < (value - b).abs() ? a : b);
return values
.reduce((a, b) => (value - a).abs() < (value - b).abs() ? a : b);
}
return FlTitlesData(
@ -2029,7 +2260,13 @@ class ChartWidget extends StatelessWidget {
if (value % 10 == 0) {
// Check if the value is in the millions or thousands range
if (value >= 1000000) {
if (value >= 1000000000000) {
formattedValue =
'${(value / 1000000000000).toStringAsFixed(0)}T';
} else if (value >= 1000000000) {
formattedValue = '${(value / 1000000000).toStringAsFixed(0)}B';
} else if (value >= 1000000) {
formattedValue = '${(value / 1000000).toStringAsFixed(0)}M';
} else if (value >= 1000) {
formattedValue = '${(value / 1000).toStringAsFixed(0)}k';
@ -2063,22 +2300,23 @@ class ChartWidget extends StatelessWidget {
interval: null,
// interval: 10, // Ensure each year is shown only once
getTitlesWidget: (value, meta) {
print('BtmTiles :-$value');
print('BtmTilesmeta :-$meta');
// if (xValues.contains(value))
double closestValue = findClosest(value, xValues);
if ((closestValue - value).abs() < 0.15)
{
if ((closestValue - value).abs() < 0.15) {
print("Bottomtiles");
print(value);
return Transform.rotate(
angle: -0.5, // Slight rotation to improve readability
return Padding(
padding: const EdgeInsets.only(top: 1.1),
child: Transform.rotate(
angle: 0.0,
// angle: -0.5, // Slight rotation to improve readability
child: Text(
value.toInt().toString(),
style: TextStyle(color: Colors.black, fontSize: 12),
),
),
);
} else {
return SizedBox.shrink(); // Hide non-relevant labels

View File

@ -273,6 +273,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
late TutorialCoachMark tutorialCoachMark;
late List<TargetFocus> homeTargets;
late List<TargetFocus> previousHomeTargets;
late final Locale locale;
void handleSkip() {
tutorialCoachMark.skip();
@ -298,6 +299,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
//Method to Start App Tour
void _showHomeTour() {
print('Home tour Arabic Started');
final homeTour = ref.watch(homeTourProvider);
final previousHomeTour = ref.watch(previousHomeTourProvider);
@ -305,6 +307,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
if (!homeTour) {
// Show Home Tour
_initTarget();
print('Home tour Target Intialized');
tutorialCoachMark = TutorialCoachMark(
paddingFocus: 0,
useSafeArea: true,
@ -345,7 +348,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
keyTarget: cardTopicKey,
shape: ShapeLightFocus.RRect,
radius: 8,
paddingFocus: 16,
paddingFocus: 10,
contents: [
createTargetContent(
text: AppLocalizations.of(context)!.home_topic,
@ -396,9 +399,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
backgroundColor: Colors.transparent,
elevation: 0,
),
child: const Text(
'Skip',
style: TextStyle(
child: Text(
AppLocalizations.of(context)!.skip,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
),
@ -418,7 +421,8 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
child: IconButton(
padding: EdgeInsets.zero,
iconSize: 20,
icon: const Icon(Icons.arrow_forward,
icon:Icon(
locale.languageCode == 'ar' ?Icons.arrow_back : Icons.arrow_forward,
color: Colors.white),
onPressed: () {
tutorialCoachMark.next();
@ -436,9 +440,13 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
),
),
TargetContent(
padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0),
padding: EdgeInsets.only(left:locale.languageCode == 'ar'
? 0
: screenWidth * 0.4, bottom: 0,right:locale.languageCode == 'ar'
? screenWidth * 0.4
: 0 ,),
align: ContentAlign.bottom,
child: Container(
child: SizedBox(
width: 200,
height: 77,
child: Stack(
@ -458,7 +466,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
keyTarget: cardsKey,
shape: ShapeLightFocus.RRect,
radius: 7,
paddingFocus: 6,
paddingFocus: 2,
// targetPosition:TargetPosition(),
contents: [
createTargetContent(
@ -507,9 +515,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
backgroundColor: Colors.transparent,
elevation: 0,
),
child: const Text(
'Skip',
style: TextStyle(
child: Text(
AppLocalizations.of(context)!.skip,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
),
@ -520,15 +528,16 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: locale.languageCode=='ar' ? Color(0xFF7DAFBC):null,
border: Border.all(
color: Colors.white, width: 2.0),
color:locale.languageCode=='ar' ? Color(0xFF7DAFBC): Colors.white, width: 2.0),
),
child: IconButton(
iconSize: 20,
icon: const Icon(Icons.arrow_back,
color: Colors.white),
icon: Icon(Icons.arrow_back,
color: Colors.white,),
onPressed: () {
tutorialCoachMark.previous();
locale.languageCode=='ar' ?tutorialCoachMark.next() : tutorialCoachMark.previous();
},
),
),
@ -536,16 +545,16 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF7DAFBC),
color: locale.languageCode=='ar' ? null:Color(0xFF7DAFBC),
border: Border.all(
color: Color(0xFF7DAFBC), width: 1),
color:locale.languageCode=='ar' ? Colors.white: Color(0xFF7DAFBC), width: 1),
),
child: IconButton(
iconSize: 20,
icon: const Icon(Icons.arrow_forward,
icon:Icon(Icons.arrow_forward,
color: Colors.white),
onPressed: () {
tutorialCoachMark.next();
locale.languageCode=='ar' ?tutorialCoachMark.previous() : tutorialCoachMark.next();
},
),
),
@ -561,7 +570,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
),
),
TargetContent(
padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0),
padding: EdgeInsets.only(left:locale.languageCode == 'ar'
? 0: screenWidth * 0.4, bottom: 0, right: locale.languageCode == 'en'
? 0: screenWidth * 0.4, ),
align: ContentAlign.bottom,
child: Container(
width: 200,
@ -622,8 +633,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
align: ContentAlign.bottom,
child: SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height *
0.5, // Set an appropriate height for the Stack
height: MediaQuery.of(context).size.height * 0.5,
child: Stack(
children: [
Positioned(
@ -660,9 +670,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
backgroundColor: Colors.transparent,
elevation: 0,
),
child: const Text(
'Skip',
style: TextStyle(
child: Text(
AppLocalizations.of(context)!.skip,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
),
@ -675,14 +685,24 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: locale.languageCode=='ar' ? Color(0xFF7DAFBC):null,
border: Border.all(
color: Colors.white, width: 2.0),
color:locale.languageCode=='ar' ? Color(0xFF7DAFBC): Colors.white, width: 2.0,),
),
child: IconButton(
icon: const Icon(Icons.arrow_back,
color: Colors.white),
iconSize: 20,
icon: Icon(Icons.arrow_back,
color: Colors.white,),
onPressed: () {
if (locale.languageCode == 'ar') {
tutorialCoachMark.finish();
ref.read(previousHomeTourProvider.notifier).state = true;
ref.read(chartsTourProvider.notifier).state = false;
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',);
} else {
tutorialCoachMark.next();
}
},
),
),
@ -690,26 +710,24 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF7DAFBC),
color: locale.languageCode=='ar' ? null:Color(0xFF7DAFBC),
border: Border.all(
color: Color(0xFF7DAFBC),
width: 1.5),
color:locale.languageCode=='ar' ? Colors.white: Color(0xFF7DAFBC), width: 1,),
),
child: IconButton(
iconSize: 20,
icon: const Icon(Icons.arrow_forward,
color: Colors.white),
onPressed: () {
ref
.read(previousHomeTourProvider
.notifier)
.state = true;
ref
.read(chartsTourProvider.notifier)
.state = false;
if (locale.languageCode == 'ar') {
tutorialCoachMark.next();
} else {
tutorialCoachMark.finish();
ref.read(previousHomeTourProvider.notifier).state = true;
ref.read(chartsTourProvider.notifier).state = false;
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
tutorialCoachMark.finish();
}
},
),
),
@ -727,7 +745,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
),
),
TargetContent(
padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0),
padding: EdgeInsets.only(left:locale.languageCode == 'ar'
? 0: screenWidth * 0.4, bottom: 0, right: locale.languageCode == 'en'
? 0: screenWidth * 0.4, ),
align: ContentAlign.bottom,
child: Container(
width: 200,
@ -788,8 +808,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
children: [
ElevatedButton(
onPressed: () {
tutorialCoachMark.skip();
debugPrint('Skip clicked');
handleSkip();
},
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
@ -799,9 +818,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
backgroundColor: Colors.transparent,
elevation: 0,
),
child: const Text(
'Skip',
style: TextStyle(
child: Text(
AppLocalizations.of(context)!.skip,
style: const TextStyle(
color: Colors.white,
fontSize: 14,
),
@ -819,8 +838,8 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
),
child: IconButton(
iconSize: 20,
icon: const Icon(Icons.arrow_forward,
color: Colors.white),
icon: Icon(locale.languageCode == 'ar' ?Icons.arrow_back : Icons.arrow_forward ,
color: Colors.white,),
onPressed: () {
tutorialCoachMark.previous();
},
@ -838,7 +857,8 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
),
),
TargetContent(
padding: EdgeInsets.only(left: screenWidth * 0.4, bottom: 0),
padding: EdgeInsets.only(left:locale.languageCode == 'ar' ? 0 : screenWidth * 0.4, bottom: 0,
right:locale.languageCode == 'ar' ? screenWidth * 0.4 : 0 ,),
align: ContentAlign.bottom,
child: Container(
width: 200,
@ -861,7 +881,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
@override
void initState() {
super.initState();
final locale = ref.read(localeProvider);
locale = ref.read(localeProvider) ?? const Locale('en');
fetchData(locale?.languageCode ?? 'en');
// _fetchUserData();
_loadLoginCount();

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
@ -22,7 +23,7 @@ class aboutFCSC extends StatelessWidget {
bottomColor: Colors.white,
mycenterTitle: true,
title: Text(
'Getting Started',
context.translate('Getting Started','البدء'),
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 22,
@ -31,15 +32,20 @@ class aboutFCSC extends StatelessWidget {
fontWeight: FontWeight.w500,
),
),
body: Container(
width: double.infinity,
body: SingleChildScrollView(
physics: ClampingScrollPhysics(),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
padding: EdgeInsets.all(16),
child: Column(children: [
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Align(
alignment: Alignment.topLeft,
child: Text(
'About FCSC',
context.translate('About FCSC','حول التطبيق'),
style: TextStyle(
fontSize: 20,
color: Color(0xFF414042),
@ -61,25 +67,26 @@ class aboutFCSC extends StatelessWidget {
),
RichText(
text: TextSpan(
text: 'The ',
text: context.translate('The ',
'تم تصميم تطبيق المركز الاتحادي للتنافسية والإحصاء (FCSC) لتوفير وصول المستخدمين المسجلين والمعتمدين إلى إحصائيات دقيقة وشاملة حول دولة الإمارات. يعمل التطبيق كمنصة مركزية لاستكشاف البيانات الرئيسية والاتجاهات والرؤى عبر مختلف القطاعات، مما يسهل الوصول إلى المعلومات الضرورية لدعم اتخاذ القرارات والتحليلات.',),
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto', height: 1.4,),
children: const <TextSpan>[
children: <TextSpan>[
TextSpan(
text:
' Federal Competitiveness and Statistics Centre (FCSC),',
style: TextStyle(
context.translate(' Federal Competitiveness and Statistics Centre (FCSC),',''),
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF414042),
fontFamily: 'Roboto'),
fontFamily: 'Roboto',),
),
TextSpan(
text:
' in your App is designed to provide registered and approved users with access to accurate and comprehensive statistics about the UAE. The app serves as a centralized platform for exploring key datasets, trends, and insights across various sectors.'),
context.translate(' in your App is designed to provide registered and approved users with access to accurate and comprehensive statistics about the UAE. The app serves as a centralized platform for exploring key datasets, trends, and insights across various sectors.',''),),
],
),
),
Spacer(),
SizedBox(height: MediaQuery.of(context).size.height*0.15),
Align(
alignment: Alignment.bottomCenter,
child: fcscBanner,
@ -89,6 +96,7 @@ class aboutFCSC extends StatelessWidget {
),
]),
),
),
);
}
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
@ -29,7 +30,7 @@ class GetStarted extends StatelessWidget {
bottomColor: Colors.white,
mycenterTitle: true,
title: Text(
'Getting Started',
context.translate('Getting Started','البدء'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -47,7 +48,7 @@ class GetStarted extends StatelessWidget {
children: [
Align(
alignment: Alignment.topLeft,
child: Text('How to Get Started',
child: Text(context.translate('How to Get Started','كيفية البدء'),
style:
TextStyle(
fontSize:20,
@ -65,13 +66,18 @@ class GetStarted extends StatelessWidget {
),
Text(
context.translate(
'1. Download the app from the App Store or Google Play Store.',
'1 .قم بتحميل التطبيق من متجر التطبيقات (Appstore) أو متجر جوجل بلاي (Google Play)..',
),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
SizedBox(height: 2,),
Text(
context.translate(
'2. Log in to access advanced features',
'2 .قم بتسجيل الدخول لفتح الميزات المتقدمة.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart';
import '../../../custom_drawer_routes.dart';
@ -27,7 +28,7 @@ class AppFeatures extends StatelessWidget {
appbarColor: Colors.white,
mycenterTitle: true,
title: Text(
'Key Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -45,7 +46,8 @@ class AppFeatures extends StatelessWidget {
children: [
Align(
alignment: Alignment.topLeft,
child: Text('App Features',
child: Text(
context.translate('App Features','الميزات الرئيسية'),
style:
TextStyle(
fontSize:20,
@ -61,7 +63,8 @@ class AppFeatures extends StatelessWidget {
fit: BoxFit.contain,
),
),
Text('1. Comprehensive Statistics:',
Text(
context.translate('1. Comprehensive Statistics:','1. رؤى مستندة إلى البيانات '),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -84,20 +87,23 @@ class AppFeatures extends StatelessWidget {
Expanded(
child: RichText(
text: TextSpan(
text: 'Access detailed datasets across categories such as ',
text:context.translate(
'Access detailed datasets across categories such as ',
'الوصول إلى مجموعات بيانات تفصيلية عبر فئات مثل الاقتصاد، البيئة، الاجتماعية، وغيرها.',),
style: TextStyle(
color:Color(0xFF898C81),
fontSize: 16,
fontFamily: 'Roboto'
),
children: const <TextSpan>[
TextSpan(text: 'Economy, Environment, Social, ',
children: <TextSpan>[
TextSpan(text:
context.translate('Economy, Environment, Social, ',''),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text: 'and more.'),
TextSpan(text:context.translate('and more.','')),
],
),
),
@ -113,8 +119,9 @@ class AppFeatures extends StatelessWidget {
), // Bullet point
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
child: Text( context.translate(
'Explore statistics presented as smart metrics, graphs, and charts for better understanding.',
'استكشاف الإحصائيات المقدمة على هيئة مقاييس ذكية ورسوم بيانية ومخططات لتعزيز الفهم.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -127,7 +134,8 @@ class AppFeatures extends StatelessWidget {
SizedBox(height: 8),
Text('2. Drilldown Navigation:',
Text(
context.translate('2. Drilldown Navigation:','2. التنقل التفصيلي'),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -149,7 +157,9 @@ class AppFeatures extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Start with high-level categories and drill down to specific KPIs and metrics for deeper insights.',
'البدء بالفئات العامة والتنقل وصولًا إلى مؤشرات الأداء الرئيسية (KPIs) والمقاييس المحددة للحصول على رؤى أعمق.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -161,7 +171,8 @@ class AppFeatures extends StatelessWidget {
),
SizedBox(height: 8),
Text('3. Interactive Visualizations:',
Text(
context.translate('3. Interactive Visualizations:','3. التصورات التفاعلية:'),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -182,8 +193,9 @@ class AppFeatures extends StatelessWidget {
), // Bullet point
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
child: Text(context.translate(
'View trends and relationships with interactive graphs and charts, including bar graphs, line charts, and more.',
'عرض الاتجاهات والعلاقات باستخدام الرسوم البيانية التفاعلية مثل المخططات الشريطية، المخططات الخطية، وغيرها.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart';
import '../../../custom_drawer_routes.dart';
@ -27,7 +28,7 @@ class ChangeMyPassword extends StatelessWidget {
appbarColor: Colors.white,
mycenterTitle: true,
title: Text(
'App Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -45,9 +46,11 @@ class ChangeMyPassword extends StatelessWidget {
children: [
Align(
alignment: Alignment.topLeft,
child: Text('How to Change My Password',
style:
TextStyle(
child: Text(
context.translate(
'How to Change My Password',
'كيفية تغيير كلمة المرور الخاصة بي',),
style: TextStyle(
fontSize:20,
color: Color(0xFF414042),
fontWeight: FontWeight.w600,
@ -62,10 +65,13 @@ class ChangeMyPassword extends StatelessWidget {
),
),
Text(
context.translate(
'Changing your password helps keep your account secure. Follow these steps to update your password:',
'يُساعد تغيير كلمة المرور في الحفاظ على أمان حسابك. اتبع هذه الخطوات لتحديث كلمة مرور',),
),
SizedBox(height: 12),
Text('Steps to Change Password',
Text(
context.translate('Steps to Change Password','خطوات تغيير كلمة المرور '),
style:TextStyle(
fontSize:22,
color: Color(0xFF414042),
@ -73,7 +79,10 @@ class ChangeMyPassword extends StatelessWidget {
),
),
SizedBox(height: 8),
Text('1. Access the Change Password Page:',
Text(
context.translate(
'1. Access the Change Password Page:',
'1. الدخول إلى صفحة تغيير كلمة المرور:',),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -96,16 +105,23 @@ class ChangeMyPassword extends StatelessWidget {
Expanded(
child: RichText(
text: TextSpan(
text: 'From the Profile page, tap on the ',
text: context.translate(
'From the Profile page, tap on the ',
'من صفحة الملف الشخصي، انقر على رابط ',),
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: '"Change Password"',
children: <TextSpan>[
TextSpan(text: context.translate(
'"Change Password"',
'"تغيير كلمة المرور" ',),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:' link at the bottom.',)
TextSpan(text:context.translate(
' link at the bottom.',
'في الأسفل.',),
),
],
),
),
@ -117,7 +133,9 @@ class ChangeMyPassword extends StatelessWidget {
),
SizedBox(height: 8),
Text('2. Enter Old Password:',
Text(context.translate(
'2. Enter Old Password:',
'2. إدخال كلمة المرور القديمة:',),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -139,7 +157,9 @@ class ChangeMyPassword extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Enter your current password in the first field.',
'أدخل كلمة المرور الحالية في الحقل الأول.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -151,7 +171,9 @@ class ChangeMyPassword extends StatelessWidget {
),
SizedBox(height: 8),
Text('3. Set a New Password:',
Text(context.translate(
'3. Set a New Password:',
'3. تعيين كلمة مرور جديدة:',),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -172,8 +194,9 @@ class ChangeMyPassword extends StatelessWidget {
), // Bullet point
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
child: Text( context.translate(
'Enter your new password in the second field.',
'أدخل كلمة المرور الجديدة في الحقل الثاني.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -190,7 +213,9 @@ class ChangeMyPassword extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Re-enter the new password in the third field for confirmation.',
'أعد إدخال كلمة المرور الجديدة في الحقل الثالث للتأكيد.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -202,7 +227,8 @@ class ChangeMyPassword extends StatelessWidget {
),
SizedBox(height: 8),
Text('4. Password Requirements:',
Text(context.translate(
'4. Password Requirements:','4. متطلبات كلمة المرور:',),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -223,8 +249,9 @@ class ChangeMyPassword extends StatelessWidget {
), // Bullet point
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
child: Text(context.translate(
'Your new password must be different from the previously used password.',
'جب أن تكون كلمة المرور الجديدة مختلفة عن كلمة المرور المستخدمة سابقًا',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -236,7 +263,8 @@ class ChangeMyPassword extends StatelessWidget {
),
SizedBox(height: 8),
Text('5. Save Your Password:',
Text(
context.translate('5. Save Your Password:','5. حفظ كلمة المرور '),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -259,16 +287,17 @@ class ChangeMyPassword extends StatelessWidget {
Expanded(
child: RichText(
text: TextSpan(
text: 'Tap the ',
text: context.translate('Tap the ','انقرعلى زر '),
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'Save ',
children: <TextSpan>[
TextSpan(text:
context.translate('Save ','"حفظ".'),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:'button',)
TextSpan(text: context.translate('button',''),)
],
),
),
@ -284,8 +313,9 @@ class ChangeMyPassword extends StatelessWidget {
), // Bullet point
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
child: Text(context.translate(
'A confirmation message will appear: “Password has been successfully updated.”',
'ستظهر رسالة تأكيد: "تم تحديث كلمة المرور بنجاح".',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -296,7 +326,8 @@ class ChangeMyPassword extends StatelessWidget {
),
),
SizedBox(height: 8),
Text('6. Re-Login:',
Text(
context.translate('6. Re-Login:','6. إعادة تسجيل الدخول'),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -317,8 +348,9 @@ class ChangeMyPassword extends StatelessWidget {
), // Bullet point
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
child: Text(context.translate(
'Log in again using your new password to continue using the app',
'قم بتسجيل الدخول مرة أخرى باستخدام كلمة المرور الجديدة للاستمرار في استخدام التطبيق.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart';
import '../../../custom_drawer_routes.dart';
@ -27,7 +28,7 @@ class EditMyProfile extends StatelessWidget {
appbarColor: Colors.white,
mycenterTitle: true,
title: Text(
'App Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -45,7 +46,8 @@ class EditMyProfile extends StatelessWidget {
children: [
Align(
alignment: Alignment.topLeft,
child: Text('How to Edit My Profile',
child: Text(
context.translate('How to Edit My Profile','كيفية تعديل ملفي الشخصي'),
style:
TextStyle(
fontSize:20,
@ -61,11 +63,13 @@ class EditMyProfile extends StatelessWidget {
fit: BoxFit.contain,
),
),
Text(
Text(context.translate(
'Editing your profile allows you to update specific information while ensuring that critical details remain secure. Follow the steps below to update your profile:',
'يتيح لك تعديل ملف التعريف الخاص بك بتحديث معلومات معينة مع ضمان أن تبقى البيانات الحساسة آمنة. اتبع الخطوات التالية لتحديث ملفك الشخصي:',),
),
SizedBox(height: 12),
Text('Steps to Edit Profile',
Text(
context.translate('Steps to Edit Profile','خطوات تعديل الملف الشخصي '),
style:TextStyle(
fontSize:22,
color: Color(0xFF414042),
@ -73,7 +77,9 @@ class EditMyProfile extends StatelessWidget {
),
),
SizedBox(height: 8),
Text('1. Access the Profile Page:',
Text(context.translate(
'1. Access the Profile Page:',
'1. الوصول إلى صفحة الملف الشخصي:',),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -95,16 +101,16 @@ class EditMyProfile extends StatelessWidget {
Expanded(
child: RichText(
text: TextSpan(
text: 'Tap on the ',
text: context.translate('Tap on the ','انقر على خيار "الملف الشخصي" من شريط التنقل في الزاوية العلوية اليسرى من الشاشة.'),
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: '"Profile"',
children: <TextSpan>[
TextSpan(text: context.translate('"Profile"',''),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:' option from the navigation bar at the top left corner of the screen.',)
TextSpan(text: context.translate(' option from the navigation bar at the top left corner of the screen.',''))
],
),
)
@ -115,7 +121,8 @@ class EditMyProfile extends StatelessWidget {
),
SizedBox(height: 8),
Text('2. Editable Fields:',
Text(
context.translate('2. Editable Fields:','2. الحقول القابلة للتعديل:'),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -139,14 +146,17 @@ class EditMyProfile extends StatelessWidget {
child: RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'Full Name:',
children: <TextSpan>[
TextSpan(text:
context.translate('Full Name:','الاسم الكامل: '),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:' Tap the text box to enter your name (up to 40 alphanumeric characters).',)
TextSpan(text:context.translate(
' Tap the text box to enter your name (up to 40 alphanumeric characters).',
'اضغط على مربع النص لإدخال اسمك (حتى 40 حرفًا أبجديًا رقميًا).',),)
],
),
)
@ -166,14 +176,19 @@ class EditMyProfile extends StatelessWidget {
child: RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'Date of Birth: ',
children: <TextSpan>[
TextSpan(
text: context.translate('Date of Birth: ','تاريخ الميلاد: '),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
fontFamily: 'Roboto',
),),
TextSpan(text:' Use the calendar dropdown to select your date of birth.',)
TextSpan(
text:context.translate(
' Use the calendar dropdown to select your date of birth.',
'استخدم القائمة المنسدلة لاختيار تاريخ ميلادك.',),
)
],
),
)
@ -193,14 +208,19 @@ class EditMyProfile extends StatelessWidget {
child: RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'Country/Region: ',
children: <TextSpan>[
TextSpan(text:context.translate(
'Country/Region: ',
'البلد/المنطقة:',),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:' Choose your current location from the dropdown menu.',),
TextSpan(text:context.translate(
' Choose your current location from the dropdown menu.',
'اختر موقعك الحالي من القائمة المنسدلة.',),
),
],
),
)
@ -220,14 +240,18 @@ class EditMyProfile extends StatelessWidget {
child: RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'User Image: ',
children: <TextSpan>[
TextSpan(text:
context.translate('User Image: ', 'الصورة الشخصية:'),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:'Tap on the avatar icon to upload or change your profile picture.',),
TextSpan(text:context.translate(
'Tap on the avatar icon to upload or change your profile picture.',
'اضغط على أيقونة رمزالصورة لتحميل أو تغيير صورة الملف الشخصي.',),
),
],
),
)
@ -239,7 +263,8 @@ class EditMyProfile extends StatelessWidget {
),
SizedBox(height: 8),
Text('3. Non-Editable Fields:',
Text(
context.translate('3. Non-Editable Fields:','3. الحقول غير القابلة للتعديل:'),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -263,21 +288,24 @@ class EditMyProfile extends StatelessWidget {
child: RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'Username ',
children: <TextSpan>[
TextSpan(text: context.translate('Username ','اسم المستخدم وعنوان البريد الإلكتروني: '),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:'and ',),
TextSpan(text: 'Email Id: ',
TextSpan(text:context.translate('and ',''),),
TextSpan(text: context.translate('Email Id: ',''),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:'These fields cannot be edited to ensure the integrity of your account.',),
TextSpan(text:context.translate(
'These fields cannot be edited to ensure the integrity of your account.',
'لا يمكن تعديل هذين الحقلين لضمان سلامة حسابك.',),
),
],
),
)
@ -289,7 +317,8 @@ class EditMyProfile extends StatelessWidget {
),
SizedBox(height: 8),
Text('4. Agree to Terms and Conditions:',
Text(
context.translate('4. Agree to Terms and Conditions:','4. الموافقة على الشروط والأحكام:'),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -311,7 +340,9 @@ class EditMyProfile extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Ensure that the checkbox for "I agree to Terms & Conditions and Privacy Policy" is selected before saving changes.',
'تأكد من تحديد خانة "أوافق على الشروط والأحكام وسياسة الخصوصية" قبل حفظ التغييرات.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -323,7 +354,8 @@ class EditMyProfile extends StatelessWidget {
),
SizedBox(height: 8),
Text('5. Save Your Changes:',
Text(
context.translate('5. Save Your Changes:','5. حفظ التغييرات:'),
style:TextStyle(
fontSize:16,
color: Color(0xFF414042),
@ -346,16 +378,21 @@ class EditMyProfile extends StatelessWidget {
Expanded(
child: RichText(
text: TextSpan(
text: 'Tap the ',
text: context.translate('Tap the ','اضغط على زر '),
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'Save',
children: <TextSpan>[
TextSpan(text:
context.translate('Save','"حفظ" '),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:' button at the bottom of the screen.',)
TextSpan(text:
context.translate(
' button at the bottom of the screen.',
'أسفل الشاشة.',),
)
],
),
),
@ -372,8 +409,10 @@ class EditMyProfile extends StatelessWidget {
), // Bullet point
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
child: Text(context.translate(
'A confirmation dialog will appear with the message: “Are you sure you want to save this page? Once saved, you will not be able to change your name or date of birth.”',
'ستظهر نافذة تأكيد برسالة:"هل أنت متأكد أنك تريد حفظ هذه الصفحة؟ بمجرد الحفظ، لن تتمكن من تغيير اسمك أو تاريخ ميلادك."',
),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -392,23 +431,23 @@ class EditMyProfile extends StatelessWidget {
Expanded(
child:RichText(
text: TextSpan(
text: 'Select ',
text: context.translate('Select ','اختر "تأكيد" لحفظ التغييرات أو "إلغاء" للرجوع.'),
style: TextStyle(fontSize: 16, color: Color(0xFF898C81), fontFamily: 'Roboto'),
children: const <TextSpan>[
TextSpan(text: 'Confirm',
children: <TextSpan>[
TextSpan(text: context.translate('Confirm',''),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:' to save the changes',),
TextSpan(text: ' Cancel',
TextSpan(text:context.translate(' to save the changes',''),),
TextSpan(text:context.translate(' Cancel',''),
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xFF414042),
fontFamily: 'Roboto'
),),
TextSpan(text:' to go back.',),
TextSpan(text:context.translate(' to go back.','')),
],
),
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart';
import '../../../custom_drawer_routes.dart';
@ -27,7 +28,7 @@ class HowUseTheApp extends StatelessWidget {
bottomColor: Colors.white,
mycenterTitle: true,
title: Text(
'Key Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -46,7 +47,7 @@ class HowUseTheApp extends StatelessWidget {
Align(
alignment: Alignment.topLeft,
child: Text(
'How to Use the App',
context.translate('How to Use the App','كيفية استخدام التطبيق:'),
style: TextStyle(
fontSize: 20,
color: Color(0xFF414042),
@ -63,7 +64,9 @@ class HowUseTheApp extends StatelessWidget {
),
),
Text(
context.translate(
'1. Registration and Approval:',
'1. التسجيل والموافقة:',),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -85,7 +88,9 @@ class HowUseTheApp extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Sign up for the app and wait for admin approval.',
'قم بالتسجيل في التطبيق وانتظر الموافقة من الإدارة.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -94,7 +99,9 @@ class HowUseTheApp extends StatelessWidget {
),
SizedBox(height: 8),
Text(
context.translate(
'2. Login and Navigation:',
'2. تسجيل الدخول والتصفح:',),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -116,7 +123,9 @@ class HowUseTheApp extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Once approved, log in to access the app. Navigate through the categories on the home screen.',
'بعد الموافقة، قم بتسجيل الدخول للوصول إلى التطبيق. تصفح الفئات المختلفة على الشاشة الرئيسية.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -125,7 +134,9 @@ class HowUseTheApp extends StatelessWidget {
),
SizedBox(height: 8),
Text(
context.translate(
'3. Access Data:',
'3. الوصول إلى البيانات:',),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -147,7 +158,9 @@ class HowUseTheApp extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Drill down into specific categories like "Economy" or "Environment" to view detailed KPIs and visual insights.',
'قم بالتعمق في الفئات المحددة مثل "الاقتصاد" أو "البيئة" لعرض مؤشرات الأداء الرئيسية والرؤى المرئية بالتفصيل.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -156,7 +169,9 @@ class HowUseTheApp extends StatelessWidget {
),
SizedBox(height: 8),
Text(
context.translate(
'4. Bookmark Metrics:',
'4. وضع إشارة مرجعية للمقاييس:',),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -178,7 +193,9 @@ class HowUseTheApp extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Drill down into specific categories like "Economy" or "Environment" to view detailed KPIs and visual insights.',
'احفظ الإحصائيات المهمة للرجوع إليها بسهولة.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart';
import '../../../custom_drawer_routes.dart';
@ -30,7 +31,7 @@ class Purpose extends StatelessWidget {
bottomColor: Colors.white,
mycenterTitle: true,
title: Text(
'Key Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -49,7 +50,7 @@ class Purpose extends StatelessWidget {
Align(
alignment: Alignment.topLeft,
child: Text(
'Purpose of the App',
context.translate('Purpose of the App','الغرض من التطبيق'),
style: TextStyle(
fontSize: 20,
color: Color(0xFF414042),
@ -81,21 +82,22 @@ class Purpose extends StatelessWidget {
Expanded(
child: RichText(
text: TextSpan(
text: 'Provide ',
text: context.translate('Provide ',
'توفير الإحصائيات الرسمية لدولة الإمارات بشكل سهل الوصول.',),
style: TextStyle(
color: Color(0xFF898C81),
fontSize: 16,
fontFamily: 'Roboto'),
children: const <TextSpan>[
children: <TextSpan>[
TextSpan(
text: 'official statistics ',
text: context.translate('official statistics ',''),
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF414042),
fontFamily: 'Roboto'),
),
TextSpan(
text: 'on the UAE in an accessible format.'),
text: context.translate('on the UAE in an accessible format.',''),),
],
),
),
@ -116,7 +118,9 @@ class Purpose extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Support decision-making and research with reliable, up-to-date data.',
'دعم اتخاذ القرارات والبحوث من خلال بيانات موثوقة ومحدثة.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -137,7 +141,9 @@ class Purpose extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Enable users to interact with data visually through graphs and metrics.',
'تمكين المستخدمين من التفاعل مع البيانات بصريًا من خلال الرسوم البيانية والمقاييس.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart';
import '../../../custom_drawer_routes.dart';
@ -30,7 +31,7 @@ class StayUpdate extends StatelessWidget {
bottomColor: Colors.white,
mycenterTitle: true,
title: Text(
'Key Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -49,7 +50,7 @@ class StayUpdate extends StatelessWidget {
Align(
alignment: Alignment.topLeft,
child: Text(
'Stay Updated',
context.translate('Stay Updated','ابقَ على اطلاع'),
style: TextStyle(
fontSize: 20,
color: Color(0xFF414042),
@ -80,7 +81,9 @@ class StayUpdate extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'The app regularly updates datasets and features to reflect the latest information. Notifications will alert you about new data or improvements.',
'يتم تحديث مجموعات البيانات وميزات التطبيق بانتظام لتعكس أحدث المعلومات. ستتلقى إشعارات تنبهك حول البيانات الجديدة والتحسينات.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import '../../../../../../infrastructure/services/img_asset_paths/banner_asset_path.dart';
import '../../../custom_drawer_routes.dart';
@ -27,7 +28,7 @@ class WhoUseTheApp extends StatelessWidget {
bottomColor: Colors.white,
mycenterTitle: true,
title: Text(
'Key Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -46,7 +47,7 @@ class WhoUseTheApp extends StatelessWidget {
Align(
alignment: Alignment.topLeft,
child: Text(
'Who can use the App?',
context.translate('Who can use the App?','من يمكنه استخدام التطبيق؟'),
style: TextStyle(
fontSize: 20,
color: Color(0xFF414042),
@ -63,7 +64,7 @@ class WhoUseTheApp extends StatelessWidget {
),
),
Text(
'This app is intended for:',
context.translate('This app is intended for:','يستهدف هذا التطبيق:'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -85,7 +86,9 @@ class WhoUseTheApp extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Government officials requiring UAE statistics for decision-making.',
'المسؤولين الحكوميين الذين يحتاجون إلى إحصاءات دولة الإمارات العربية المتحدة لاتخاذ القرارات.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -106,7 +109,9 @@ class WhoUseTheApp extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Business professionals and researchers analyzing market trends.',
'المتخصصين في مجال الأعمال والباحثين الذين يقومون بتحليل اتجاهات السوق.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),
@ -127,7 +132,9 @@ class WhoUseTheApp extends StatelessWidget {
SizedBox(width: 8), // Space between bullet and text
Expanded(
child: Text(
context.translate(
'Students and educators needing reliable data for study and teaching.',
'الطلاب والمعلمين الذين يحتاجون إلى بيانات موثوقة للدراسة والتعليم.',),
textAlign: TextAlign.justify, // Align the text
softWrap: true,
),

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
@ -22,7 +23,7 @@ class aboutTheApp extends StatelessWidget {
appbarColor: Colors.white,
mycenterTitle: true,
title: Text(
'Getting Started',
context.translate('Getting Started','البدء'),
style: TextStyle(
fontSize: 22,
fontFamily: 'Roboto',
@ -41,7 +42,7 @@ class aboutTheApp extends StatelessWidget {
border: Border(
bottom: BorderSide(
color: Colors.grey.shade300,
width: 0.5), // Grey bottom line
width: 0.5,), // Grey bottom line
),
),
child: ListTile(
@ -50,7 +51,7 @@ class aboutTheApp extends StatelessWidget {
},
tileColor: Colors.white,
title: Text(
'About FCSC',
context.translate('About FCSC','حول التطبيق'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -75,7 +76,7 @@ class aboutTheApp extends StatelessWidget {
},
// tileColor: Colors.white,
title: Text(
'How to Get Started?',
context.translate('How to Get Started?','كيفية البدء'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
@ -25,7 +26,7 @@ class _FAQPageState extends State<FAQPage> {
bottomColor: Colors.white,
mycenterTitle: true,
title: Text(
' FAQs',
context.translate(' FAQs','الأسئلة الشائعة'),
style: TextStyle(
fontSize: 22,
color: Color(0xFF7DAFBC),
@ -67,11 +68,14 @@ class QuestionAnswerScrollView extends StatelessWidget {
final List<Map<String, dynamic>> questionsAndAnswers = [
{
'question': 'What is the purpose of this app?',
'question-ar': 'ما هو الغرض من هذا التطبيق؟',
'answer':
'The app provides official UAE statistics across categories like Economy, Environment, and Social. It allows users to explore datasets, view trends, and access detailed metrics to make informed decisions.'
'The app provides official UAE statistics across categories like Economy, Environment, and Social. It allows users to explore datasets, view trends, and access detailed metrics to make informed decisions.',
'answer-ar':'يوفر التطبيق الإحصائيات الرسمية لدولة الإمارات العربية المتحدة عبر فئات مثل الاقتصاد والبيئة والاجتماعية . يتيح للمستخدمين استكشاف مجموعات البيانات، عرض الاتجاهات، والوصول إلى المقاييس التفصيلية لاتخاذ قرارات مستنيرة.',
},
{
'question': 'Do I need to create an account to use the app?',
'question-ar': 'هل أحتاج إلى إنشاء حساب لاستخدام التطبيق؟ ',
'answer': RichText(
text: TextSpan(
children: [
@ -101,14 +105,46 @@ class QuestionAnswerScrollView extends StatelessWidget {
],
),
),
'answer-ar':RichText(
text: TextSpan(
children: [
TextSpan(
text:
'نعم، التطبيق مخصص فقط للمستخدمين المسجلين والمعتمدين. للوصول إلى البيانات:\n\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
TextSpan(
text:
' 1. يجب عليك التسجيل باستخدام خيار "التسجيل الآن" في شاشة تسجيل الدخول.\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
TextSpan(
text: ' 2. يجب أن يتم الموافقة على تسجيلك من قبل المسؤول.\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
TextSpan(
text:
" بعد الموافقة، يمكنك تسجيل الدخول للوصول إلى ميزات التطبيق وبياناته.\n\n لا يتوفر الوصول للزوار في هذا التطبيق.\n",
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
],
),
),
},
{
'question': 'How can I navigate through the app?',
'question-ar': 'كيف يمكنني التنقل عبر التطبيق؟',
'answer':
'• Use the main categories on the homepage (e.g., Economy, Environment) to access subcategories and detailed KPIs.\n• Drill down into specific metrics or graphical views by tapping on a KPI.\n• Access additional features like Bookmarks or Profile through the navigation bar.\n'
'• Use the main categories on the homepage (e.g., Economy, Environment) to access subcategories and detailed KPIs.\n• Drill down into specific metrics or graphical views by tapping on a KPI.\n• Access additional features like Bookmarks or Profile through the navigation bar.\n',
'answer-ar': '•استخدم الفئات الرئيسية الموجودة على الصفحة الرئيسية (مثل: الاقتصاد، البيئة) للوصول إلى الفئات الفرعية ومؤشرات الأداء الرئيسية التفصيلية •\n\ قم بالتعمق في مؤشرات معينة أو عرض الرسوم البيانية من خلال النقر على مؤشر الأداء الرئيسي (KPI). \n • للوصول إلى ميزات إضافية مثل الإشارات المرجعية أو الملف الشخصي، استخدم شريط التنقل.\n',
},
{
'question': 'What types of data are available?',
'question-ar':'ما أنواع البيانات المتوفرة؟ ',
'answer': RichText(
text: TextSpan(
children: [
@ -118,7 +154,7 @@ class QuestionAnswerScrollView extends StatelessWidget {
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
TextSpan(
text: ' • Economy',
text: ' • Economy:',
style: TextStyle(
color: Color(0xFF414042),
fontWeight: FontWeight.w500,
@ -157,9 +193,58 @@ class QuestionAnswerScrollView extends StatelessWidget {
],
),
),
'answer-ar':RichText(
text: TextSpan(
children: [
TextSpan(
text: 'يوفر التطبيق بيانات عن:\n\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
TextSpan(
text: ' • الاقتصاد:',
style: TextStyle(
color: Color(0xFF414042),
fontWeight: FontWeight.w500,
fontSize: 16),
),
TextSpan(
text: ' الناتج المحلي الإجمالي (GDP)، معدلات النمو، والاتجاهات الاقتصادية.\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
TextSpan(
text: ' • البيئة:',
style: TextStyle(
color: Color(0xFF414042),
fontWeight: FontWeight.w500,
fontSize: 16),
),
TextSpan(
text: ' إنتاج الكهرباء، استهلاك المياه، وغيرها.\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
TextSpan(
text: ' • الاجتماعية:',
style: TextStyle(
color: Color(0xFF414042),
fontWeight: FontWeight.w500,
fontSize: 16),
),
TextSpan(
text:
' توزيع القوى العاملة، معدلات المشاركة، والبيانات الديموغرافية.\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
],
),
),
},
{
'question': 'How do I bookmark a metric?',
'question-ar': 'كيف يمكنني وضع مؤشر في الإشارات المرجعية؟',
'answer': RichText(
text: TextSpan(
children: [
@ -195,9 +280,22 @@ class QuestionAnswerScrollView extends StatelessWidget {
],
),
),
'answer-ar':RichText(
text: TextSpan(
children: [
TextSpan(
text: 'عند عرض المؤشر، اضغط على أيقونة الإشارة المرجعية. يمكنك الوصول إلى الإشارات المرجعية الخاصة بك من قسم "إشاراتي المرجعية" في شريط التنقل.',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
],
),
),
},
{
'question': 'Can I view the app in another language?',
'question-ar':'هل يمكنني عرض التطبيق بلغة أخرى؟',
'answer': RichText(
text: TextSpan(
children: [
@ -234,29 +332,49 @@ class QuestionAnswerScrollView extends StatelessWidget {
],
),
),
'answer-ar':RichText(
text: TextSpan(
children: [
TextSpan(
text: 'نعم، التطبيق يدعم اللغتين الإنجليزية والعربية. يمكنك تبديل اللغة باستخدام المفتاح الموجود في الزاوية العلوية اليمنى من التطبيق.',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
],
),
),
},
{
'question': 'What happens if I forget my password?',
'question-ar':'ماذا يحدث إذا نسيت كلمة المرور الخاصة بي؟',
'answer':
'Tap on the Forgot Password? link on the login page. Follow the steps to reset your password via your registered email address.\n'
'Tap on the Forgot Password? link on the login page. Follow the steps to reset your password via your registered email address.\n',
'answer-ar':'انقر على رابط "نسيت كلمة المرور؟" في صفحة تسجيل الدخول. اتبع الخطوات لإعادة تعيين كلمة المرور الخاصة بك عبر عنوان بريدك الإلكتروني المسجل.',
},
{
'question': 'Can I edit my profile details?',
'question-ar':'هل يمكنني تعديل تفاصيل الملف الشخصي؟',
'answer':
'Yes, you can edit specific fields such as Date of Birth and User Image. However, certain fields like Username and Email are non-editable for security reasons.\n'
'Yes, you can edit specific fields such as Date of Birth and User Image. However, certain fields like Username and Email are non-editable for security reasons.\n',
'answer-ar':'يتم تحديث مجموعات البيانات في التطبيق بشكل منتظم لضمان وصول المستخدمين إلى أحدث الإحصاءات. يتم إرسال إشعارات عند إجراء تحديثات مهمة.',
},
{
'question': 'How often is the data updated?',
'question-ar':'كم مرة يتم تحديث البيانات؟ ',
'answer':
'The app updates its datasets regularly to ensure users have access to the latest statistics. Notifications are sent whenever significant updates are made.\n'
'The app updates its datasets regularly to ensure users have access to the latest statistics. Notifications are sent whenever significant updates are made.\n',
'answer-ar':'يتم تحديث مجموعات البيانات في التطبيق بشكل منتظم لضمان وصول المستخدمين إلى أحدث الإحصاءات. يتم إرسال إشعارات عند إجراء تحديثات مهمة.',
},
{
'question': 'What types of graphs and charts are available?',
'question-ar':'ما أنواع الرسوم البيانية والمخططات المتوفرة؟ ',
'answer':
'The app provides a variety of visualizations, including:\n • Line charts for trends.\n • Bar and column charts for comparisons.\n • Stacked charts for multi-layered data views.\n'
'The app provides a variety of visualizations, including:\n • Line charts for trends.\n • Bar and column charts for comparisons.\n • Stacked charts for multi-layered data views.\n',
'answer-ar':'يوفر التطبيق مجموعة متنوعة من التصورات البيانية، بما في ذلك:\n• المخططات الخطية لعرض الاتجاهات.\n• المخططات الشريطية والعمودية للمقارنات.\n• المخططات المكدسة لعرض البيانات متعددة الطبقات.\n',
},
{
'question': 'Can I share the data or charts?',
'question-ar':'هل يمكنني مشاركة البيانات أو الرسوم البيانية؟',
'answer': RichText(
text: TextSpan(
children: [
@ -281,9 +399,22 @@ class QuestionAnswerScrollView extends StatelessWidget {
],
),
),
'answer-ar':RichText(
text: TextSpan(
children: [
TextSpan(
text:
'نعم، يمكنك مشاركة البيانات أو الرسوم البيانية مباشرة من التطبيق من خلال النقر على زر "مشاركة" المتوفر في معظم الصفحات.',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
],
),
),
},
{
'question': 'What should I do if I encounter an issue?',
'question-ar':'ماذا يجب أن أفعل إذا واجهت مشكلة؟ ',
'answer': RichText(
text: TextSpan(
children: [
@ -307,9 +438,21 @@ class QuestionAnswerScrollView extends StatelessWidget {
],
),
),
'answer-ar': RichText(
text: TextSpan(
children: [
TextSpan(
text: 'للحصول على الدعم الفني أو تقديم ملاحظات، انتقل إلى قسم "المساعدة" في التطبيق وتواصل مع فريق الدعم.\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
),
],
),
),
},
{
'question': 'How do I log out of the app?',
'question-ar':'كيف يمكنني تسجيل الخروج من التطبيق؟',
'answer': RichText(
text: TextSpan(
children: [
@ -345,6 +488,17 @@ class QuestionAnswerScrollView extends StatelessWidget {
],
),
),
'answer-ar':RichText(
text: TextSpan(
children: [
TextSpan(
text: 'انتقل إلى قسم "الملف الشخصي" واضغط على خيار "تسجيل الخروج" في الزاوية العلوية اليسرى.\n',
style: TextStyle(
color: Colors.grey, fontSize: 16, fontFamily: 'Roboto'),
)
],
),
),
},
];
@ -388,7 +542,7 @@ class _QuestionAnswerCardState extends State<QuestionAnswerCard> {
dense: true,
textColor: Color(0xFF414042),
title: Text(
widget.qa['question']!,
context.translate(widget.qa['question'],widget.qa['question-ar'])!,
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16),
),
trailing: Icon(isExpanded
@ -404,10 +558,10 @@ class _QuestionAnswerCardState extends State<QuestionAnswerCard> {
Padding(
padding: const EdgeInsets.only(
left: 16, right: 16, bottom: 16, top: 0),
child: widget.qa['answer'] is RichText
? widget.qa['answer']
child:widget.qa['answer'] is RichText
? context.translate(widget.qa['answer'],widget.qa['answer-ar'])
: Text(
widget.qa['answer'] ?? '',
context.translate(widget.qa['answer'] ?? '',widget.qa['answer-ar']),
style: TextStyle(
color: Colors.grey,
fontSize: 16,

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
@ -23,7 +24,7 @@ class UsingFeatures extends StatelessWidget {
appbarColor: Colors.white,
mycenterTitle: true,
title: Text(
'Key Features',
context.translate('Key Features','الميزات الرئيسية'),
style: TextStyle(
fontSize: 22,
fontFamily: 'Roboto',
@ -51,7 +52,7 @@ class UsingFeatures extends StatelessWidget {
},
tileColor: Colors.white,
title: Text(
'App Features',
context.translate('App Features','الميزات الرئيسية '),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -76,7 +77,7 @@ class UsingFeatures extends StatelessWidget {
},
// tileColor: Colors.white,
title: Text(
'Who can use The App?',
context.translate('Who can use The App?','يمكنه استخدام التطبيق?'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -105,7 +106,7 @@ class UsingFeatures extends StatelessWidget {
},
// tileColor: Colors.white,
title: Text(
'Purpose of the App',
context.translate('Purpose of the App','ض من التطبيق'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -134,7 +135,7 @@ class UsingFeatures extends StatelessWidget {
},
// tileColor: Colors.white,
title: Text(
'How to Use the App',
context.translate('How to Use the App','كيفية استخدام التطبيق'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -163,7 +164,7 @@ class UsingFeatures extends StatelessWidget {
},
// tileColor: Colors.white,
title: Text(
'Stay Updated',
context.translate('Stay Updated','ابق على اطلاع'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -192,7 +193,7 @@ class UsingFeatures extends StatelessWidget {
},
// tileColor: Colors.white,
title: Text(
'How to Change My Password',
context.translate('How to Change My Password','كيفية تغيير كلمة المرور الخاصة بي'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),
@ -221,7 +222,7 @@ class UsingFeatures extends StatelessWidget {
},
// tileColor: Colors.white,
title: Text(
'How to Edit My Profile',
context.translate('How to Edit My Profile','كيفية تعديل ملفي الشخصي'),
style: TextStyle(
fontSize: 16,
color: Color(0xFF414042),

View File

@ -1,10 +1,13 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:iconify_design/iconify_design.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class Userguide extends StatefulWidget {
Userguide({super.key});
const Userguide({super.key});
@override
State<Userguide> createState() => _UserguideState();
@ -12,12 +15,11 @@ class Userguide extends StatefulWidget {
class _UserguideState extends State<Userguide> {
final List<Map<String, dynamic>> guideList = [
{'routePath':'aboutApp','color': Color(0xFF90B0D5), 'text': 'Getting Started', 'icon': 'cbi:start-tv', },
{'routePath':'features','color': Color(0xFFAA8E83), 'text': 'Using Features', 'icon': 'pajamas:issue-type-feature',},
{'routePath':'faq','color': Color(0xFF7296BE), 'text': 'FAQs', 'icon': 'mdi:faq',},
{'routePath':'aboutApp','color': Color(0xFF90B0D5), 'text': 'Getting Started', 'icon': 'cbi:start-tv', 'text-ar': 'البدء' },
{'routePath':'features','color': Color(0xFFAA8E83), 'text': 'Using Features', 'icon': 'pajamas:issue-type-feature', 'text-ar' : 'استخدام الميزات'},
{'routePath':'faq','color': Color(0xFF7296BE), 'text': 'FAQs', 'icon': 'mdi:faq', 'text-ar': 'لأسئلة الشائعة'},
];
@override
Widget buildDynamicWidget(dynamic icons, Color color) {
if (icons is IconData) {
return Icon(
@ -44,6 +46,7 @@ class _UserguideState extends State<Userguide> {
}
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
@ -56,7 +59,7 @@ class _UserguideState extends State<Userguide> {
bottomColor: Colors.white,
dividerColor: Colors.grey[300],
appbarColor: Colors.white,
title: Text('User Guide') ,
title: Text(AppLocalizations.of(context)!.guide_title) ,
body: Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 16 , vertical: 20),
@ -71,7 +74,7 @@ class _UserguideState extends State<Userguide> {
itemBuilder: (context, index) {
return HoverContainer(
iconName: guideList[index]['icon'],
title: guideList[index]['text'],
title: context.translate(guideList[index]['text'], guideList[index]['text-ar']),
routePath: guideList[index]['routePath'],
);
},
@ -118,7 +121,7 @@ class _HoverContainerState extends State<HoverContainer> {
boxShadow: isHovered
? [
BoxShadow(
color: Colors.black.withOpacity(0.2),
color: Colors.black.withValues(alpha:0.2),
blurRadius:2,
spreadRadius: 1,
offset: Offset(0, 4),
@ -127,7 +130,7 @@ class _HoverContainerState extends State<HoverContainer> {
: [],
border: Border.all(
color: Color(0xFF7DAFBC),
width: 1.0
width: 1.0,
),
),
alignment: Alignment.center,
@ -151,7 +154,7 @@ class _HoverContainerState extends State<HoverContainer> {
decoration: BoxDecoration(
color: Color(0xFF7DAFBC),
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Color(0xFF7DAFBC))
border: Border.all(color: Color(0xFF7DAFBC)),
),
child: Text(
widget.title,
@ -164,7 +167,7 @@ class _HoverContainerState extends State<HoverContainer> {
),
],
);
})
},),
),

View File

@ -81,11 +81,13 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
bool isLoggedOut = false;
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
static final _repo = getIt.call<TAuthRepo>();
late final Locale locale;
@override
void initState() {
super.initState();
_checkUserId();
locale = ref.read(localeProvider)?? const Locale('en');
WidgetsBinding.instance.addPostFrameCallback((_) {
_startAppbarTour();
});
@ -200,23 +202,24 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: locale.languageCode=='ar' ? Color(0xFF7DAFBC):null,
border: Border.all(
color: Colors.white, width: 2.0),
color:locale.languageCode=='ar' ? Color(0xFF7DAFBC): Colors.white, width: 2.0),
),
child: IconButton(
icon: const Icon(Icons.arrow_back,
color: Colors.white),
color: Colors.white,),
onPressed: () {
if (locale.languageCode == 'ar') {
tutorialCoachMark.next();
} else {
tutorialCoachMark.finish();
ref
.read(scaffoldTourProvider.notifier)
.state = true;
ref
.read(previousChartsTourProvider
.notifier)
.state = false;
ref.read(scaffoldTourProvider.notifier).state = true;
ref.read(previousChartsTourProvider.notifier).state = false;
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',);
}
},
),
),
@ -224,15 +227,23 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF7DAFBC),
color: locale.languageCode=='ar' ? null:Color(0xFF7DAFBC),
border: Border.all(
color: Color(0xFF7DAFBC), width: 1.5),
color:locale.languageCode=='ar' ? Colors.white: Color(0xFF7DAFBC), width: 1),
),
child: IconButton(
icon: const Icon(Icons.arrow_forward,
color: Colors.white),
onPressed: () {
if (locale.languageCode == 'ar') {
tutorialCoachMark.finish();
ref.read(scaffoldTourProvider.notifier).state = true;
ref.read(previousChartsTourProvider.notifier).state = false;
context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments',);
} else {
tutorialCoachMark.next();
}
},
),
),
@ -260,7 +271,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
text: AppLocalizations.of(context)!.mainMenu,
alignment: ContentAlign.bottom,
gap: 55,
space: 0,
space:locale.languageCode=='ar' ? 20: 20,
),
TargetContent(
align: ContentAlign.bottom,
@ -316,14 +327,15 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: locale.languageCode=='ar' ? Color(0xFF7DAFBC):null,
border: Border.all(
color: Colors.white, width: 2.0),
color:locale.languageCode=='ar' ? Color(0xFF7DAFBC): Colors.white, width: 2.0,),
),
child: IconButton(
icon: const Icon(Icons.arrow_back,
color: Colors.white),
color: Colors.white,),
onPressed: () {
tutorialCoachMark.previous();
locale.languageCode=='ar' ?tutorialCoachMark.next() : tutorialCoachMark.previous();
},
),
),
@ -331,15 +343,15 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xFF7DAFBC),
color: locale.languageCode=='ar' ? null:Color(0xFF7DAFBC),
border: Border.all(
color: Color(0xFF7DAFBC), width: 1),
color:locale.languageCode=='ar' ? Colors.white: Color(0xFF7DAFBC), width: 1),
),
child: IconButton(
icon: const Icon(Icons.arrow_forward,
color: Colors.white),
color: Colors.white,),
onPressed: () {
tutorialCoachMark.next();
locale.languageCode=='ar' ?tutorialCoachMark.previous() : tutorialCoachMark.next();
},
),
),
@ -355,15 +367,17 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
),
),
TargetContent(
padding: EdgeInsets.only(right: screenWidth * 0.7, top: 30),
align: ContentAlign.right,
padding: EdgeInsets.only(right:locale.languageCode=='ar' ? 0: screenWidth * 0.7, top: locale.languageCode=='ar' ?20 : 20, left: locale.languageCode=='ar' ? screenWidth * 0.7:0,),
align: locale.languageCode=='ar' ? ContentAlign.left : ContentAlign.right,
child: Container(
width: 200,
height: screenHeight / 4,
child: Stack(
children: [
Image.asset(
'assets/app_tour/leftDown.png',
locale.languageCode == 'ar'
? 'assets/app_tour/down_right.png' // Arabic locale image
: 'assets/app_tour/leftDown.png', // Default image
fit: BoxFit.contain,
),
// Positioned(
@ -438,7 +452,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
elevation: 0,
),
child: Text(
// 'Skip',
AppLocalizations.of(context)!.skip,
style: TextStyle(
color: Colors.white,
@ -455,8 +469,8 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
color: Colors.white, width: 2.0),
),
child: IconButton(
icon: const Icon(Icons.arrow_back,
color: Colors.white),
icon: Icon(locale.languageCode=='ar' ? Icons.arrow_forward: Icons.arrow_back,
color: Colors.white,),
onPressed: () {
tutorialCoachMark.previous();
},
@ -466,25 +480,12 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
ElevatedButton(
onPressed: () {
debugPrint('Got it clicked');
ref
.read(chartsTourProvider.notifier)
.state = true;
ref
.read(
previousChartsTourProvider.notifier)
.state = true;
ref.read(homeTourProvider.notifier).state =
true;
ref
.read(previousHomeTourProvider.notifier)
.state = true;
ref
.read(scaffoldTourProvider.notifier)
.state = true;
ref
.read(previousScaffoldTourProvider
.notifier)
.state = true;
ref.read(chartsTourProvider.notifier).state = true;
ref.read(previousChartsTourProvider.notifier).state = true;
ref.read(homeTourProvider.notifier).state = true;
ref.read(previousHomeTourProvider.notifier).state = true;
ref.read(scaffoldTourProvider.notifier).state = true;
ref.read(previousScaffoldTourProvider.notifier).state = true;
tutorialCoachMark.finish();
},
style: ElevatedButton.styleFrom(
@ -515,30 +516,22 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
),
),
TargetContent(
padding:
EdgeInsets.only(left: screenWidth * 0.7, top: toggleHeight),
align: ContentAlign.left,
padding: EdgeInsets.only(left: locale.languageCode=='ar' ? 0: screenWidth * 0.7,
top: toggleHeight,
right: locale.languageCode=='ar' ? screenWidth * 0.7 : 0,
),
align : locale.languageCode=='ar' ? ContentAlign.right :ContentAlign.left,
child: Container(
width: 200,
height: screenHeight / 4,
child: Stack(
children: [
Image.asset(
'assets/app_tour/down_right.png',
locale.languageCode == 'ar'
? 'assets/app_tour/leftDown.png' // Arabic locale image
: 'assets/app_tour/down_right.png', // Default image
fit: BoxFit.contain,
),
// Positioned(
// top: 0,
// left: MediaQuery.of(context).size.width* 0.5,
// child: SizedBox(
// width: 50,
// height: 100,
// child: Image.asset(
// 'assets/app_tour/bookmark2.png',
// fit: BoxFit.contain,
// ),
// ),
// ),
)
],
),
),

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.19+20
version: 1.0.23+24
environment:
sdk: ">=3.2.3 <4.0.0"