User Guide Update
This commit is contained in:
commit
8520970592
BIN
assets/icons/drawer/logout.png
Normal file
BIN
assets/icons/drawer/logout.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@ -294,7 +294,8 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/faq_page.dart';
|
import 'package:uae_stat/presentation/Screens/auth_verification/registration.dart';
|
||||||
|
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/getting_started.dart';
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
||||||
|
|
||||||
import '../domain/use_cases/preferences_use_case.dart';
|
import '../domain/use_cases/preferences_use_case.dart';
|
||||||
@ -305,10 +306,11 @@ import '../presentation/Screens/auth_verification/otp_verification.dart';
|
|||||||
import '../presentation/Screens/profilepage.dart';
|
import '../presentation/Screens/profilepage.dart';
|
||||||
import '../presentation/routes/auth_routes/login_route.dart';
|
import '../presentation/routes/auth_routes/login_route.dart';
|
||||||
import '../presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
import '../presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
||||||
|
import '../presentation/routes/drawer_routes/Drawer Items/edit_profile.dart';
|
||||||
import '../presentation/routes/drawer_routes/Drawer Items/feedback.dart';
|
import '../presentation/routes/drawer_routes/Drawer Items/feedback.dart';
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/features.dart';
|
import '../presentation/routes/drawer_routes/Drawer Items/user_guide/faq_page.dart';
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/getting_started.dart';
|
import '../presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart';
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/user_guide.dart';
|
import '../presentation/routes/drawer_routes/Drawer Items/user_guide/user_guide.dart';
|
||||||
import '../presentation/routes/drawer_routes/Drawer Items/manage_users.dart';
|
import '../presentation/routes/drawer_routes/Drawer Items/manage_users.dart';
|
||||||
|
|
||||||
final GoRouter router = GoRouter(
|
final GoRouter router = GoRouter(
|
||||||
@ -316,12 +318,16 @@ final GoRouter router = GoRouter(
|
|||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
//builder: (context, state) => LoginRoute(),
|
//builder: (context, state) => LoginRoute(),
|
||||||
builder: (context, state) => MyHomePage(),
|
builder: (context, state) => LoginRoute(),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/myhomepage',
|
path: '/myhomepage',
|
||||||
builder: (context, state) => MyHomePage(),
|
builder: (context, state) => MyHomePage(),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/register',
|
||||||
|
builder: (context, state) => RegisterScreen(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/mailverification',
|
path: '/mailverification',
|
||||||
builder: (context, state) => EmailVerificationScreen(
|
builder: (context, state) => EmailVerificationScreen(
|
||||||
@ -333,10 +339,11 @@ final GoRouter router = GoRouter(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/changepassword',
|
path: '/changepassword/:userId',
|
||||||
builder: (context, state) => Changepassword(
|
builder: (context, state) {
|
||||||
userId: '',
|
final userId = state.pathParameters['userId']!;
|
||||||
),
|
return Changepassword(userId: userId);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/createNewPw/:userId/:email',
|
path: '/createNewPw/:userId/:email',
|
||||||
@ -359,11 +366,13 @@ final GoRouter router = GoRouter(
|
|||||||
path: '/feedback',
|
path: '/feedback',
|
||||||
builder: (context, state) => FeedbackForm(),
|
builder: (context, state) => FeedbackForm(),
|
||||||
),
|
),
|
||||||
|
//Sub route
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/profile',
|
path: '/profile/:userId',
|
||||||
builder: (context, state) => ProfileScreen(
|
builder: (context, state) {
|
||||||
userId: '',
|
final userId = state.pathParameters['userId']!;
|
||||||
),
|
return ProfileScreen(userId: userId);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/user-guide',
|
path: '/user-guide',
|
||||||
@ -373,14 +382,17 @@ final GoRouter router = GoRouter(
|
|||||||
name: 'features',
|
name: 'features',
|
||||||
builder: (context, state) => UsingFeatures(),
|
builder: (context, state) => UsingFeatures(),
|
||||||
),
|
),
|
||||||
GoRoute(path: '/gettingStarted',
|
|
||||||
name: 'gettingStarted',
|
GoRoute(path: '/faq',
|
||||||
builder: (context, state) => GettingStarted(),
|
name: 'faq',
|
||||||
),
|
builder: (context, state) => FAQPage(),
|
||||||
GoRoute(path: '/faq',
|
),
|
||||||
name: 'faq',
|
|
||||||
builder: (context, state) => FAQPage(),
|
|
||||||
),
|
GoRoute(path: '/gettingStarted',
|
||||||
|
name: 'gettingStarted',
|
||||||
|
builder: (context, state) => GettingStarted(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// GoRoute(
|
// GoRoute(
|
||||||
@ -391,10 +403,13 @@ final GoRouter router = GoRouter(
|
|||||||
// return ManageUserRouter(title: title);
|
// return ManageUserRouter(title: title);
|
||||||
// },
|
// },
|
||||||
// ),
|
// ),
|
||||||
|
GoRoute(
|
||||||
|
path: '/editProfile',
|
||||||
|
builder: (context, state) => EditProfile(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/manageuser',
|
path: '/manageuser',
|
||||||
builder: (context, state) => ManageUserRouter(),
|
builder: (context, state) => ManageUserRouter(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import 'package:pocketbase/pocketbase.dart';
|
|||||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||||
import 'package:uae_stat/presentation/Screens/profilepage.dart';
|
import 'package:uae_stat/presentation/Screens/profilepage.dart';
|
||||||
|
|
||||||
import '../../../infrastructure/services/pocketbase_service.dart';
|
|
||||||
import '../../routes/auth_routes/login_route.dart';
|
import '../../routes/auth_routes/login_route.dart';
|
||||||
|
|
||||||
class RegisterScreen extends StatefulWidget {
|
class RegisterScreen extends StatefulWidget {
|
||||||
@ -136,77 +135,27 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// String? _validatePassword(String? value) {
|
|
||||||
// // Define the regular expression for allowed characters
|
|
||||||
// final regex = RegExp(
|
|
||||||
// r'^[A-Za-z0-9~!@#$%^&*()_+=[\]{}|;:,.<>?/-àèìòùáéíóúÀÈÌÒÙÁÉÍÓÚ]*$');
|
|
||||||
//
|
|
||||||
// if (value == null || value.isEmpty) {
|
|
||||||
// return 'Required';
|
|
||||||
// } else if (value.length < 8) {
|
|
||||||
// return 'Password must be at least 8characters';
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Check the length constraint
|
|
||||||
// if (value.length < 8 || value.length > 40) {
|
|
||||||
// return 'Password must be between 8 and 64 characters';
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Check the regular expression
|
|
||||||
// if (!regex.hasMatch(value)) {
|
|
||||||
// return 'Password contains invalid characters';
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// _password = value; // Store the password for confirm password validation
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
String? _validatePassword(String? value) {
|
String? _validatePassword(String? value) {
|
||||||
// Define the regular expression for allowed characters
|
// Define the regular expression for allowed characters
|
||||||
final regex = RegExp(
|
final regex = RegExp(
|
||||||
r'^[A-Za-z0-9~!@#$%^&*()_+=[\]{}|;:,.<>?/-àèìòùáéíóúÀÈÌÒÙÁÉÍÓÚ]*$');
|
r'^[A-Za-z0-9~!@#$%^&*()_+=[\]{}|;:,.<>?/-àèìòùáéíóúÀÈÌÒÙÁÉÍÓÚ]*$');
|
||||||
|
|
||||||
// Define regular expressions for password complexity requirements
|
|
||||||
final hasUppercase = RegExp(r'[A-Z]');
|
|
||||||
final hasLowercase = RegExp(r'[a-z]');
|
|
||||||
final hasDigit = RegExp(r'\d');
|
|
||||||
final hasSpecialCharacter = RegExp(r'[~!@#$%^&*()_+=[\]{}|;:,.<>?/-]');
|
|
||||||
|
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return 'Required';
|
return 'Required';
|
||||||
|
} else if (value.length < 8) {
|
||||||
|
return 'Password must be at least 8characters';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the length constraint
|
// Check the length constraint
|
||||||
if (value.length < 8 || value.length > 64) {
|
if (value.length < 8 || value.length > 40) {
|
||||||
return 'Password must be between 8 and 64 characters';
|
return 'Password must be between 8 and 64 characters';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the regular expression for allowed characters
|
// Check the regular expression
|
||||||
if (!regex.hasMatch(value)) {
|
if (!regex.hasMatch(value)) {
|
||||||
return 'Password contains invalid characters';
|
return 'Password contains invalid characters';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track missing constraints
|
|
||||||
List<String> missingConstraints = [];
|
|
||||||
|
|
||||||
if (!hasUppercase.hasMatch(value)) {
|
|
||||||
missingConstraints.add('uppercase letter');
|
|
||||||
}
|
|
||||||
if (!hasLowercase.hasMatch(value)) {
|
|
||||||
missingConstraints.add('lowercase letter');
|
|
||||||
}
|
|
||||||
if (!hasDigit.hasMatch(value)) {
|
|
||||||
missingConstraints.add('numeric digit');
|
|
||||||
}
|
|
||||||
if (!hasSpecialCharacter.hasMatch(value)) {
|
|
||||||
missingConstraints.add('special character');
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are missing constraints, return a consolidated message
|
|
||||||
if (missingConstraints.isNotEmpty) {
|
|
||||||
return 'At least one ${missingConstraints.join(', ')}';
|
|
||||||
}
|
|
||||||
|
|
||||||
_password = value; // Store the password for confirm password validation
|
_password = value; // Store the password for confirm password validation
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -233,12 +182,46 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
if (_formKey.currentState?.validate() ?? false) {
|
if (_formKey.currentState?.validate() ?? false) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
try {
|
try {
|
||||||
final existingUsers = await pb.collection('users').getList(
|
final adminAuth = await pb.admins
|
||||||
filter: 'email="${_emailController.text}"',
|
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||||
);
|
|
||||||
|
|
||||||
if (existingUsers.items.isNotEmpty) {
|
final adminToken = adminAuth.token;
|
||||||
// Email already exists
|
print('adminToken- ${adminToken}');
|
||||||
|
// Create user in PocketBase
|
||||||
|
final response = await pb.collection('users').create(body: {
|
||||||
|
'username': _usernameController.text,
|
||||||
|
'email': _emailController.text,
|
||||||
|
'password': _passwordController.text,
|
||||||
|
'passwordConfirm': _passwordController.text,
|
||||||
|
'status': 'Pending',
|
||||||
|
}, headers: {
|
||||||
|
'Authorization': adminToken
|
||||||
|
});
|
||||||
|
if (response.id != null) {
|
||||||
|
userID = response.id;
|
||||||
|
// Request email verification
|
||||||
|
// PocketBaseService.users.requestVerification(_emailController.text);
|
||||||
|
// Show success message instead of navigating away
|
||||||
|
setState(() {
|
||||||
|
userID = response.id;
|
||||||
|
registrationSuccess = true;
|
||||||
|
registrationFailed = false; // Show success message on success
|
||||||
|
});
|
||||||
|
|
||||||
|
// Navigate to ProfileScreen after successful registration
|
||||||
|
// Navigator.pushReplacement(
|
||||||
|
// context,
|
||||||
|
// MaterialPageRoute(
|
||||||
|
// builder: (context) => ProfileScreen(userId: response.id)),
|
||||||
|
// );
|
||||||
|
} else {
|
||||||
|
throw Exception('User registration failed: missing user ID');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Check if the error is due to an invalid or already used email
|
||||||
|
if (e
|
||||||
|
.toString()
|
||||||
|
.contains('The email is invalid or already in use.')) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
@ -255,43 +238,14 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return; // Stop registration process
|
|
||||||
}
|
|
||||||
final adminAuth = await pb.admins
|
|
||||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
|
||||||
|
|
||||||
final adminToken = adminAuth.token;
|
|
||||||
print('adminToken- ${adminToken}');
|
|
||||||
// Create user in PocketBase
|
|
||||||
final response = await pb.collection('users').create(body: {
|
|
||||||
'username': _usernameController.text,
|
|
||||||
'email': _emailController.text,
|
|
||||||
'password': _passwordController.text,
|
|
||||||
'passwordConfirm': _passwordController.text,
|
|
||||||
'status': 'Pending',
|
|
||||||
'role': 'user',
|
|
||||||
}, headers: {
|
|
||||||
'Authorization': adminToken
|
|
||||||
});
|
|
||||||
if (response.id != null) {
|
|
||||||
userID = response.id;
|
|
||||||
// Request email verification
|
|
||||||
// PocketBaseService.users.requestVerification(_emailController.text);
|
|
||||||
// Show success message instead of navigating away
|
|
||||||
setState(() {
|
|
||||||
userID = response.id;
|
|
||||||
registrationSuccess = true;
|
|
||||||
registrationFailed = false; // Show success message on success
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
throw Exception('User registration failed: missing user ID');
|
// Handle other types of errors
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
setState(() {
|
setState(() {
|
||||||
registrationFailed = true;
|
registrationFailed = true;
|
||||||
registrationSuccess = false;
|
registrationSuccess = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
showError = true; // Show error if checkbox is not checked
|
showError = true; // Show error if checkbox is not checked
|
||||||
@ -344,7 +298,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
buildIconContainer(Icons.report, Color(0xFF7DAFBC)),
|
buildIconContainer(Icons.report, Color(0xFF7DAFBC)),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
Text(
|
Text(
|
||||||
"Your registration is pending for verification",
|
"Your registration is pending for Admin Approval.",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
@ -353,7 +307,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
"Kindly verify your mail to proceed further.",
|
"Access will be granted once your account is approved.",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@ -362,8 +316,14 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () => {
|
||||||
context.go('/');
|
Navigator.pushReplacement(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => LoginRoute()
|
||||||
|
|
||||||
|
//ProfileScreen(userId: userID)
|
||||||
|
),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Go to Login',
|
'Go to Login',
|
||||||
@ -452,7 +412,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: screenheight / 6),
|
SizedBox(height: screenheight / 15),
|
||||||
Text(
|
Text(
|
||||||
'Register',
|
'Register',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@ -518,8 +478,8 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
_obscurePassword
|
_obscurePassword
|
||||||
? Icons.visibility_off
|
? Icons.visibility
|
||||||
: Icons.visibility,
|
: Icons.visibility_off,
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -550,8 +510,8 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
_obscureConfirmPassword
|
_obscureConfirmPassword
|
||||||
? Icons.visibility_off
|
? Icons.visibility
|
||||||
: Icons.visibility,
|
: Icons.visibility_off,
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -662,7 +622,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
width: screenwidth / 1.3,
|
width: screenwidth / 1.3,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// Add your login logic here
|
context.go('/');
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Color(
|
backgroundColor: Color(
|
||||||
@ -671,44 +631,41 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// child: Row(
|
|
||||||
// mainAxisSize: MainAxisSize.min,
|
|
||||||
// children: [
|
|
||||||
// Text(
|
|
||||||
// "Login",
|
|
||||||
// style: TextStyle(
|
|
||||||
// fontSize: 16, color: Colors.white
|
|
||||||
// ),
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// ),
|
|
||||||
// SizedBox(width: 8),
|
|
||||||
// Icon(Icons.arrow_forward,
|
|
||||||
// color: Colors.white),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
// Navigate to LoginRoute
|
|
||||||
context.go('/');
|
|
||||||
},
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Login",
|
"Login",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16, color: Colors.white),
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Icon(Icons.arrow_forward,
|
Icon(Icons.arrow_forward,
|
||||||
color: Colors.white),
|
color: Colors.white),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
|
// child: GestureDetector(
|
||||||
|
// onTap: () {
|
||||||
|
// // Navigate to LoginRoute
|
||||||
|
// context.go('/');
|
||||||
|
// },
|
||||||
|
// child: Row(
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// "Login",
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 16,
|
||||||
|
// color: Colors.white,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(width: 8),
|
||||||
|
// Icon(Icons.arrow_forward,
|
||||||
|
// color: Colors.white),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
|||||||
@ -1,29 +1,262 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:async';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:syncfusion_flutter_charts/charts.dart'; // Import Syncfusion charts package
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
void main() {
|
||||||
|
runApp(MyApp());
|
||||||
import '../components/my_drawer.dart';
|
|
||||||
|
|
||||||
class DemoHome extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
State<DemoHome> createState() => _DemoHomeState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DemoHomeState extends State<DemoHome> {
|
class MyApp extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return MaterialApp(
|
||||||
drawer: const MyDrawer(),
|
home: ChartPage(),
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: const Color(0xFFf8f9ff),
|
|
||||||
title: Text(context.translate('Home', 'نموذج الملاحظات')),
|
|
||||||
),
|
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Center(
|
|
||||||
child: Text('Home Page'),
|
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ChartPage extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
ChartPageState createState() => ChartPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChartPageState extends State<ChartPage> {
|
||||||
|
List<dynamic> chartsData = [];
|
||||||
|
bool isLoading = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
fetchChartData();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> fetchChartData() async {
|
||||||
|
const baseUrl =
|
||||||
|
'https://pb.venbait.in/api/custom/apicall'; // Replace with your server URL
|
||||||
|
final url = Uri.parse('$baseUrl?dataset=hotels');
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await http.get(url);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
setState(() {
|
||||||
|
chartsData = jsonDecode(response.body);
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to load data');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
print('Error fetching data: $error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ChartData> parseLineChartData(List<dynamic> response) {
|
||||||
|
return response.map((entry) {
|
||||||
|
// Attempt to fetch the TIMEPERIOD
|
||||||
|
final rawTimePeriod =
|
||||||
|
entry['ObsKey']?['Year'] ?? entry['ObsKey']?['TIME_PERIOD'];
|
||||||
|
final formattedTimePeriod = rawTimePeriod != null
|
||||||
|
? rawTimePeriod.toString() // Use as-is if valid
|
||||||
|
: 'Unknown'; // Fallback value if null
|
||||||
|
|
||||||
|
// Parse the value or fallback to 0.0
|
||||||
|
final value =
|
||||||
|
double.tryParse(entry['ObsValue']?['Value']?.toString() ?? '0.0') ??
|
||||||
|
0.0;
|
||||||
|
|
||||||
|
return ChartData(
|
||||||
|
timePeriod: formattedTimePeriod,
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ChartData> parseBarChartData(List<dynamic> response) {
|
||||||
|
return response
|
||||||
|
.asMap()
|
||||||
|
.entries
|
||||||
|
.map((entry) => ChartData(
|
||||||
|
timePeriod: entry.value['ObsKey']['TIME_PERIOD'] ??
|
||||||
|
'Unknown', // Fallback to 'Unknown' if null
|
||||||
|
value: double.tryParse(
|
||||||
|
entry.value['ObsValue']['Value'].toString()) ??
|
||||||
|
0.0, // Handle null/invalid value
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildChart(dynamic chartData) {
|
||||||
|
print('chartData $chartData');
|
||||||
|
switch (chartData['chart_type']) {
|
||||||
|
case 'line':
|
||||||
|
return SfCartesianChart(
|
||||||
|
primaryXAxis: CategoryAxis(
|
||||||
|
title: AxisTitle(text: 'Year'),
|
||||||
|
labelRotation: 45, // Rotate labels if they overlap
|
||||||
|
),
|
||||||
|
title: ChartTitle(text: 'Hotel Estabhlishments'),
|
||||||
|
legend: Legend(isVisible: true),
|
||||||
|
tooltipBehavior: TooltipBehavior(
|
||||||
|
enable: true,
|
||||||
|
builder: (dynamic data, dynamic point, dynamic series,
|
||||||
|
int pointIndex, int seriesIndex) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'${data.timePeriod}: ${formatNumber(data.value)}',
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
series: <CartesianSeries<ChartData, String>>[
|
||||||
|
LineSeries<ChartData, String>(
|
||||||
|
dataSource: parseLineChartData(chartData['response']),
|
||||||
|
xValueMapper: (ChartData data, _) => data.timePeriod,
|
||||||
|
yValueMapper: (ChartData data, _) => data.value,
|
||||||
|
name: chartData['dataset'],
|
||||||
|
color: Colors.red,
|
||||||
|
dataLabelSettings: DataLabelSettings(
|
||||||
|
isVisible: true,
|
||||||
|
builder: (dynamic data, dynamic point, dynamic series,
|
||||||
|
int pointIndex, int seriesIndex) {
|
||||||
|
return Text(
|
||||||
|
formatNumber(data.value),
|
||||||
|
style: const TextStyle(fontSize: 12, color: Colors.black),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
case 'bar':
|
||||||
|
return SfCartesianChart(
|
||||||
|
primaryXAxis: CategoryAxis(),
|
||||||
|
title: ChartTitle(text: 'Hotel Occupancy Rate'),
|
||||||
|
tooltipBehavior: TooltipBehavior(
|
||||||
|
enable: true,
|
||||||
|
builder: (dynamic data, dynamic point, dynamic series,
|
||||||
|
int pointIndex, int seriesIndex) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'${data.timePeriod}: ${formatNumber(data.value)}',
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
series: <CartesianSeries<ChartData, String>>[
|
||||||
|
BarSeries<ChartData, String>(
|
||||||
|
dataSource: parseBarChartData(chartData['response']),
|
||||||
|
xValueMapper: (ChartData data, _) => data.timePeriod,
|
||||||
|
yValueMapper: (ChartData data, _) => data.value,
|
||||||
|
name: chartData['dataset'],
|
||||||
|
color: Colors.red,
|
||||||
|
dataLabelSettings: DataLabelSettings(
|
||||||
|
isVisible: true,
|
||||||
|
builder: (dynamic data, dynamic point, dynamic series,
|
||||||
|
int pointIndex, int seriesIndex) {
|
||||||
|
return Text(
|
||||||
|
formatNumber(data.value),
|
||||||
|
style: const TextStyle(fontSize: 12, color: Colors.black),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
// isTrackVisible: true,
|
||||||
|
// trackColor: Colors.red
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return Center(child: Text('Unknown chart type'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFF7DAFBC),
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Color(0xFF7DAFBC),
|
||||||
|
elevation: 0,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios_new, color: Colors.white),
|
||||||
|
onPressed: () {
|
||||||
|
context.go('/myhomepage');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
'Charts',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: isLoading
|
||||||
|
? Center(child: CircularProgressIndicator())
|
||||||
|
: ListView.builder(
|
||||||
|
itemCount: chartsData.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Card(
|
||||||
|
margin: EdgeInsets.all(10),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Text(
|
||||||
|
// 'Chart: ${chartsData[index]['chart_type']}',
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 18, fontWeight: FontWeight.bold),
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: 10),
|
||||||
|
Container(
|
||||||
|
height: 300,
|
||||||
|
child: buildChart(chartsData[index]),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChartData {
|
||||||
|
final String timePeriod;
|
||||||
|
final double value;
|
||||||
|
final String formattedValue;
|
||||||
|
|
||||||
|
ChartData({required this.timePeriod, required this.value})
|
||||||
|
: formattedValue = formatNumber(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatNumber(double value) {
|
||||||
|
if (value >= 1e12) {
|
||||||
|
return '${(value / 1e12).toStringAsFixed(2)} T'; // Trillions
|
||||||
|
} else if (value >= 1e9) {
|
||||||
|
return '${(value / 1e9).toStringAsFixed(2)} B'; // Billions
|
||||||
|
} else if (value >= 1e6) {
|
||||||
|
return '${(value / 1e6).toStringAsFixed(2)} M'; // Millions
|
||||||
|
} else if (value >= 1e5) {
|
||||||
|
return '${(value / 1e5).toStringAsFixed(2)} L'; // Lakhs
|
||||||
|
} else if (value >= 1e3) {
|
||||||
|
return '${(value / 1e3).toStringAsFixed(2)} K'; // Thousands
|
||||||
|
}
|
||||||
|
return value.toStringAsFixed(2); // Default to two decimal places
|
||||||
|
}
|
||||||
|
|||||||
@ -156,17 +156,39 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void _pickImage() async {
|
||||||
|
// final XFile? pickedFile =
|
||||||
|
// await _picker.pickImage(source: ImageSource.gallery);
|
||||||
|
// if (pickedFile != null) {
|
||||||
|
// setState(() {
|
||||||
|
// _profileImage = File(pickedFile.path);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Function to open the date picker
|
||||||
|
|
||||||
void _pickImage() async {
|
void _pickImage() async {
|
||||||
final XFile? pickedFile =
|
final XFile? pickedFile =
|
||||||
await _picker.pickImage(source: ImageSource.gallery);
|
await _picker.pickImage(source: ImageSource.gallery);
|
||||||
if (pickedFile != null) {
|
if (pickedFile != null) {
|
||||||
|
final String fileExtension =
|
||||||
|
pickedFile.path.split('.').last.toLowerCase();
|
||||||
|
if (fileExtension == 'jpg' ||
|
||||||
|
fileExtension == 'jpeg' ||
|
||||||
|
fileExtension == 'png' ||
|
||||||
|
fileExtension == "heic") {
|
||||||
setState(() {
|
setState(() {
|
||||||
_profileImage = File(pickedFile.path);
|
_profileImage = File(pickedFile.path);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Please select a JPG, JPEG, or PNG file.')),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to open the date picker
|
|
||||||
Future<void> _pickDate() async {
|
Future<void> _pickDate() async {
|
||||||
final DateTime today = DateTime.now();
|
final DateTime today = DateTime.now();
|
||||||
final DateTime initialDate = _selectedDate ??
|
final DateTime initialDate = _selectedDate ??
|
||||||
@ -273,11 +295,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
_resetFormFields();
|
_resetFormFields();
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text("Profile updated successfully!")));
|
SnackBar(content: Text("Profile updated successfully!")));
|
||||||
if (role == 'admin') {
|
// if (role == 'admin') {
|
||||||
context.go('/manageuser');
|
// context.go('/manageuser');
|
||||||
} else {
|
// } else {
|
||||||
|
// context.go('/myhomepage');
|
||||||
|
// }
|
||||||
context.go('/myhomepage');
|
context.go('/myhomepage');
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text("Failed to update profile: $error")));
|
SnackBar(content: Text("Failed to update profile: $error")));
|
||||||
@ -370,8 +393,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"User Name",
|
"User Name",
|
||||||
style:
|
style: TextStyle(
|
||||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -380,7 +405,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
controller: _usernameController,
|
controller: _usernameController,
|
||||||
focusNode: _focusNodes[0],
|
focusNode: _focusNodes[0],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: _showHints[0] ? 'Mohammad Hassan' : null,
|
hintText: _showHints[0] ? 'Enter the User Name' : null,
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
@ -393,9 +418,11 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"E-mail",
|
"Email ID",
|
||||||
style:
|
style: TextStyle(
|
||||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -418,7 +445,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Full Name",
|
"Full Name*",
|
||||||
style:
|
style:
|
||||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
@ -444,7 +471,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
controller: _fullNameController,
|
controller: _fullNameController,
|
||||||
focusNode: _focusNodes[2],
|
focusNode: _focusNodes[2],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: _showHints[2] ? 'Enter the Full Name' : null,
|
hintText: _showHints[2] ? 'Enter the name' : null,
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
@ -473,9 +500,9 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
hintText:
|
hintText: _showHints[3] ? 'DD/MM/YYYY' : null,
|
||||||
_showHints[3] ? 'Select your Date of Birth' : null,
|
//_showHints[3] ? 'Select your Date of Birth' : null,
|
||||||
//hintText: 'Select your Date of Birth',
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
suffixIcon: const Icon(Icons.arrow_drop_down_sharp),
|
suffixIcon: const Icon(Icons.arrow_drop_down_sharp),
|
||||||
),
|
),
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
|
|||||||
@ -740,206 +740,204 @@ class _LoginRouteState extends State<LoginRoute> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// <<<<<<< HEAD
|
|
||||||
// // =======
|
// final form = Form(
|
||||||
// final form = Form(
|
// key: formKey,
|
||||||
// key: formKey,
|
// child: Column(
|
||||||
// child: Column(
|
// children: [
|
||||||
// children: [
|
// ThemedFormField(
|
||||||
// ThemedFormField(
|
// hintText: context.translate(
|
||||||
// hintText: context.translate(
|
// 'Email',
|
||||||
// 'Email',
|
// 'بريد إلكتروني',
|
||||||
// 'بريد إلكتروني',
|
// ),
|
||||||
// ),
|
// validator: FieldValidator.email(),
|
||||||
// validator: FieldValidator.email(),
|
// imgPath: MiscIconAssetPath.person,
|
||||||
// imgPath: MiscIconAssetPath.person,
|
// controller: emailCtl,
|
||||||
// controller: emailCtl,
|
// ),
|
||||||
// ),
|
// 15.verticalSpace,
|
||||||
// 15.verticalSpace,
|
// ThemedFormField(
|
||||||
// ThemedFormField(
|
// validator: (text) {
|
||||||
// validator: (text) {
|
// if (text!.length < 8) {
|
||||||
// if (text!.length < 8) {
|
// return 'The password must be at least 8 characters';
|
||||||
// return 'The password must be at least 8 characters';
|
// }
|
||||||
// }
|
// return FieldValidator.password(minLength: 8)(text);
|
||||||
// return FieldValidator.password(minLength: 8)(text);
|
// },
|
||||||
// },
|
// hintText: context.translate(
|
||||||
// hintText: context.translate(
|
// 'Password',
|
||||||
// 'Password',
|
// 'كلمة المرور',
|
||||||
// 'كلمة المرور',
|
// ),
|
||||||
// ),
|
// imgPath: MiscIconAssetPath.lock,
|
||||||
// imgPath: MiscIconAssetPath.lock,
|
// controller: pwCtl,
|
||||||
// controller: pwCtl,
|
// isObscurable: true,
|
||||||
// isObscurable: true,
|
// ),
|
||||||
// ),
|
// // 6.verticalSpace,
|
||||||
// // 6.verticalSpace,
|
// Align(
|
||||||
// Align(
|
// alignment: AlignmentDirectional.topEnd,
|
||||||
// alignment: AlignmentDirectional.topEnd,
|
// child: forgotPwBtn,
|
||||||
// child: forgotPwBtn,
|
// ),
|
||||||
// ),
|
// 10.verticalSpace,
|
||||||
// 10.verticalSpace,
|
// loginBtn,
|
||||||
// loginBtn,
|
// ],
|
||||||
// ],
|
// ),
|
||||||
// ),
|
// );
|
||||||
// );
|
// final helloAndPleaseLoginTexts = Column(
|
||||||
// final helloAndPleaseLoginTexts = Column(
|
// children: [
|
||||||
// children: [
|
// Text(
|
||||||
// Text(
|
// context.translate(
|
||||||
// context.translate(
|
// 'Hello Again!',
|
||||||
// 'Hello Again!',
|
// 'مرحبا مجددا!',
|
||||||
// 'مرحبا مجددا!',
|
// ),
|
||||||
// ),
|
// style: TextStyle(
|
||||||
// style: TextStyle(
|
// fontFamily: context.translate(
|
||||||
// fontFamily: context.translate(
|
// 'Roboto',
|
||||||
// 'Roboto',
|
// 'NotoKufi',
|
||||||
// 'NotoKufi',
|
// ),
|
||||||
// ),
|
// fontSize: 40,
|
||||||
// fontSize: 40,
|
// fontWeight: FontWeight.w300,
|
||||||
// fontWeight: FontWeight.w300,
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// 10.verticalSpace,
|
||||||
// 10.verticalSpace,
|
// Text(
|
||||||
// Text(
|
// context.translate(
|
||||||
// context.translate(
|
// 'Please login to access UAE’s key official statistics',
|
||||||
// 'Please login to access UAE’s key official statistics',
|
// 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة',
|
||||||
// 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة',
|
// ),
|
||||||
// ),
|
// textAlign: TextAlign.center,
|
||||||
// textAlign: TextAlign.center,
|
// style: TextStyle(
|
||||||
// style: TextStyle(
|
// fontFamily: context.translate(
|
||||||
// fontFamily: context.translate(
|
// 'Roboto',
|
||||||
// 'Roboto',
|
// 'NotoKufi',
|
||||||
// 'NotoKufi',
|
// ),
|
||||||
// ),
|
// fontSize: 18,
|
||||||
// fontSize: 18,
|
// color: const Color(0xff898C81),
|
||||||
// color: const Color(0xff898C81),
|
// fontWeight: FontWeight.w700,
|
||||||
// fontWeight: FontWeight.w700,
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ],
|
||||||
// ],
|
// );
|
||||||
// );
|
// final dontHaveAnAccountRegisterBtn = TextButton(
|
||||||
// final dontHaveAnAccountRegisterBtn = TextButton(
|
// onPressed: () => {
|
||||||
// onPressed: () => {
|
// Navigator.push(
|
||||||
// Navigator.push(
|
// context,
|
||||||
// context,
|
// MaterialPageRoute(builder: (context) => RegisterScreen()),
|
||||||
// MaterialPageRoute(builder: (context) => RegisterScreen()),
|
// ),
|
||||||
// ),
|
// },
|
||||||
// },
|
// child: Text.rich(
|
||||||
// child: Text.rich(
|
// textAlign: TextAlign.center,
|
||||||
// textAlign: TextAlign.center,
|
// TextSpan(
|
||||||
// TextSpan(
|
// style: TextStyle(
|
||||||
// style: TextStyle(
|
// fontFamily: context.translate(
|
||||||
// fontFamily: context.translate(
|
// 'Roboto',
|
||||||
// 'Roboto',
|
// 'NotoKufi',
|
||||||
// 'NotoKufi',
|
// ),
|
||||||
// ),
|
// fontSize: 18,
|
||||||
// fontSize: 18,
|
// fontWeight: FontWeight.bold,
|
||||||
// fontWeight: FontWeight.bold,
|
// ),
|
||||||
// ),
|
// children: [
|
||||||
// children: [
|
// TextSpan(
|
||||||
// TextSpan(
|
// text: context.translate(
|
||||||
// text: context.translate(
|
// 'Don\'t have an account? ',
|
||||||
// 'Don\'t have an account? ',
|
// 'ليس لديك حساب؟',
|
||||||
// 'ليس لديك حساب؟',
|
// ),
|
||||||
// ),
|
// style: const TextStyle(
|
||||||
// style: const TextStyle(
|
// color: Color(0xff898C81),
|
||||||
// color: Color(0xff898C81),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// const TextSpan(
|
||||||
// const TextSpan(
|
// text: ' ',
|
||||||
// text: ' ',
|
// ),
|
||||||
// ),
|
// TextSpan(
|
||||||
// TextSpan(
|
// text: context.translate(
|
||||||
// text: context.translate(
|
// 'Register Now',
|
||||||
// 'Register Now',
|
// 'سجل الان',
|
||||||
// 'سجل الان',
|
// ),
|
||||||
// ),
|
// style: TextStyle(
|
||||||
// style: TextStyle(
|
// color: MyTheme.topicColor(IndicatorTopic.economy).shade600,
|
||||||
// color: MyTheme.topicColor(IndicatorTopic.economy).shade600,
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ],
|
||||||
// ],
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// );
|
||||||
// );
|
// final continueAsGuestBtn = SizedBox(
|
||||||
// final continueAsGuestBtn = SizedBox(
|
// width: double.infinity,
|
||||||
// width: double.infinity,
|
// child: ElevatedButton(
|
||||||
// child: ElevatedButton(
|
// onPressed: () => context
|
||||||
// onPressed: () => context
|
// .go('/${context.language}/${BottomNavBarItem.home.routePath}'),
|
||||||
// .go('/${context.language}/${BottomNavBarItem.home.routePath}'),
|
// style: ButtonStyle(
|
||||||
// style: ButtonStyle(
|
// shape: WidgetStatePropertyAll(
|
||||||
// shape: WidgetStatePropertyAll(
|
// RoundedRectangleBorder(
|
||||||
// RoundedRectangleBorder(
|
// borderRadius: BorderRadius.circular(10),
|
||||||
// borderRadius: BorderRadius.circular(10),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// padding: const WidgetStatePropertyAll(
|
||||||
// padding: const WidgetStatePropertyAll(
|
// EdgeInsets.symmetric(vertical: 10.5),
|
||||||
// EdgeInsets.symmetric(vertical: 10.5),
|
// ),
|
||||||
// ),
|
// textStyle: WidgetStatePropertyAll(
|
||||||
// textStyle: WidgetStatePropertyAll(
|
// TextStyle(
|
||||||
// TextStyle(
|
// fontFamily: context.translate(
|
||||||
// fontFamily: context.translate(
|
// 'Roboto',
|
||||||
// 'Roboto',
|
// 'NotoKufi',
|
||||||
// 'NotoKufi',
|
// ),
|
||||||
// ),
|
// fontSize: 16,
|
||||||
// fontSize: 16,
|
// fontWeight: FontWeight.w600,
|
||||||
// fontWeight: FontWeight.w600,
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// backgroundColor: WidgetStatePropertyAll(
|
||||||
// backgroundColor: WidgetStatePropertyAll(
|
// MyTheme.topicColor(IndicatorTopic.environment),
|
||||||
// MyTheme.topicColor(IndicatorTopic.environment),
|
// ),
|
||||||
// ),
|
// foregroundColor: const WidgetStatePropertyAll(
|
||||||
// foregroundColor: const WidgetStatePropertyAll(
|
// Colors.white,
|
||||||
// Colors.white,
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// child: Row(
|
||||||
// child: Row(
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
// children: [
|
||||||
// children: [
|
// Text(
|
||||||
// Text(
|
// context.translate(
|
||||||
// context.translate(
|
// 'Continue as Guest',
|
||||||
// 'Continue as Guest',
|
// 'استمر كضيف',
|
||||||
// 'استمر كضيف',
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// 6.horizontalSpace,
|
||||||
// 6.horizontalSpace,
|
// const Icon(Icons.chevron_right_outlined),
|
||||||
// const Icon(Icons.chevron_right_outlined),
|
// ],
|
||||||
// ],
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// );
|
||||||
// );
|
// final fcscBanner = Image.asset(
|
||||||
// final fcscBanner = Image.asset(
|
// BannerAssetPath.fcsc,
|
||||||
// BannerAssetPath.fcsc,
|
// height: 56,
|
||||||
// height: 56,
|
// );
|
||||||
// );
|
// final screenWidth = MediaQuery.of(context).size.width;
|
||||||
// final screenWidth = MediaQuery.of(context).size.width;
|
// final listViewHorizontalPadding =
|
||||||
// final listViewHorizontalPadding =
|
// screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2;
|
||||||
// screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2;
|
// final scaffoldBody = ListView(
|
||||||
// final scaffoldBody = ListView(
|
// padding: EdgeInsets.symmetric(
|
||||||
// padding: EdgeInsets.symmetric(
|
// horizontal: listViewHorizontalPadding.toDouble(),
|
||||||
// horizontal: listViewHorizontalPadding.toDouble(),
|
// ),
|
||||||
// ),
|
// children: [
|
||||||
// children: [
|
// 36.verticalSpace,
|
||||||
// 36.verticalSpace,
|
// const Align(
|
||||||
// const Align(
|
// alignment: AlignmentDirectional.topEnd,
|
||||||
// alignment: AlignmentDirectional.topEnd,
|
// child: LangToggle(),
|
||||||
// child: LangToggle(),
|
// ),
|
||||||
// ),
|
// 16.verticalSpace,
|
||||||
// 16.verticalSpace,
|
// helloAndPleaseLoginTexts,
|
||||||
// helloAndPleaseLoginTexts,
|
// 42.verticalSpace,
|
||||||
// 42.verticalSpace,
|
// form,
|
||||||
// form,
|
// 20.verticalSpace,
|
||||||
// 20.verticalSpace,
|
// dontHaveAnAccountRegisterBtn,
|
||||||
// dontHaveAnAccountRegisterBtn,
|
// 36.verticalSpace,
|
||||||
// 36.verticalSpace,
|
// continueAsGuestBtn,
|
||||||
// continueAsGuestBtn,
|
// 72.verticalSpace,
|
||||||
// 72.verticalSpace,
|
// fcscBanner,
|
||||||
// fcscBanner,
|
// ],
|
||||||
// ],
|
// );
|
||||||
// );
|
// final bgScaffold = Scaffold(
|
||||||
// final bgScaffold = Scaffold(
|
// backgroundColor: Colors.white,
|
||||||
// backgroundColor: Colors.white,
|
// body: SafeArea(child: scaffoldBody),
|
||||||
// body: SafeArea(child: scaffoldBody),
|
// );
|
||||||
// );
|
// return bgScaffold;
|
||||||
// return bgScaffold;
|
|
||||||
// >>>>>>> b0c5ebce3deb7da2aa24b0ea5ffe684df7dfb7bf
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -161,6 +161,7 @@
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
import '../../drawer_routes/custom_drawer_routes.dart';
|
import '../../drawer_routes/custom_drawer_routes.dart';
|
||||||
|
|
||||||
class MyHomePage extends StatefulWidget {
|
class MyHomePage extends StatefulWidget {
|
||||||
@ -176,16 +177,16 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
double myheight = MediaQuery.of(context).size.height;
|
double myheight = MediaQuery.of(context).size.height;
|
||||||
double mywidth = MediaQuery.of(context).size.width;
|
double mywidth = MediaQuery.of(context).size.width;
|
||||||
return BaseScaffold(
|
return BaseScaffold(
|
||||||
title: Center(child: SizedBox(height : myheight/5, width : mywidth/3,child: Image(image: AssetImage('assets/logos/uae_stat.png')))),
|
title: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
height: myheight / 5,
|
||||||
|
width: mywidth / 3,
|
||||||
|
child: Image(image: AssetImage('assets/logos/uae_stat.png')))),
|
||||||
body: EconomyStats(),
|
body: EconomyStats(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EconomyStats extends StatelessWidget {
|
class EconomyStats extends StatelessWidget {
|
||||||
const EconomyStats({Key? key}) : super(key: key);
|
const EconomyStats({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@ -193,7 +194,7 @@ class EconomyStats extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(left: 10,right: 10),
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Header Section
|
// Header Section
|
||||||
@ -210,7 +211,9 @@ class EconomyStats extends StatelessWidget {
|
|||||||
|
|
||||||
// ECONOMY DETAILS
|
// ECONOMY DETAILS
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 10,),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 10,
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// First Row
|
// First Row
|
||||||
@ -228,7 +231,8 @@ class EconomyStats extends StatelessWidget {
|
|||||||
title: 'Inflation Rate',
|
title: 'Inflation Rate',
|
||||||
subtitle: '(2022)',
|
subtitle: '(2022)',
|
||||||
value: '4.82%',
|
value: '4.82%',
|
||||||
bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC),
|
bordercolor: Color(0xFF7DAFBC),
|
||||||
|
textcolor: Color(0xFF7DAFBC),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -241,13 +245,15 @@ class EconomyStats extends StatelessWidget {
|
|||||||
title: 'Trade Value',
|
title: 'Trade Value',
|
||||||
subtitle: '(Jan - Jan 2024) - AED',
|
subtitle: '(Jan - Jan 2024) - AED',
|
||||||
value: '215.4B',
|
value: '215.4B',
|
||||||
bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC),
|
bordercolor: Color(0xFF7DAFBC),
|
||||||
|
textcolor: Color(0xFF7DAFBC),
|
||||||
),
|
),
|
||||||
InfoCard(
|
InfoCard(
|
||||||
title: 'Hotel Guests',
|
title: 'Hotel Guests',
|
||||||
subtitle: '(2022)',
|
subtitle: '(2022)',
|
||||||
value: '25.21M',
|
value: '25.21M',
|
||||||
bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC),
|
bordercolor: Color(0xFF7DAFBC),
|
||||||
|
textcolor: Color(0xFF7DAFBC),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -264,7 +270,9 @@ class EconomyStats extends StatelessWidget {
|
|||||||
|
|
||||||
// SOCIAL DETAILS
|
// SOCIAL DETAILS
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 10,),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 10,
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// First Row
|
// First Row
|
||||||
@ -321,12 +329,15 @@ class EconomyStats extends StatelessWidget {
|
|||||||
|
|
||||||
// ENVIRONMENT DETAILS
|
// ENVIRONMENT DETAILS
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 10,),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 10,
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// First Row
|
// First Row
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
InfoCard(
|
InfoCard(
|
||||||
title: 'Electricity',
|
title: 'Electricity',
|
||||||
@ -347,7 +358,8 @@ class EconomyStats extends StatelessWidget {
|
|||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
// Second Row
|
// Second Row
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
InfoCard(
|
InfoCard(
|
||||||
title: 'Export of oil',
|
title: 'Export of oil',
|
||||||
@ -386,13 +398,11 @@ class RoundedCornerContainer extends StatelessWidget {
|
|||||||
final Color backgroundColor;
|
final Color backgroundColor;
|
||||||
final TextStyle? textStyle;
|
final TextStyle? textStyle;
|
||||||
|
|
||||||
|
|
||||||
const RoundedCornerContainer({
|
const RoundedCornerContainer({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.text,
|
required this.text,
|
||||||
this.backgroundColor = Colors.blue,
|
this.backgroundColor = Colors.blue,
|
||||||
this.textStyle,
|
this.textStyle,
|
||||||
|
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -417,7 +427,6 @@ class RoundedCornerContainer extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class InfoCard extends StatelessWidget {
|
class InfoCard extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final String subtitle;
|
final String subtitle;
|
||||||
@ -429,18 +438,24 @@ class InfoCard extends StatelessWidget {
|
|||||||
Key? key,
|
Key? key,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.subtitle,
|
required this.subtitle,
|
||||||
required this.value, required this.bordercolor,this.textcolor,
|
required this.value,
|
||||||
|
required this.bordercolor,
|
||||||
|
this.textcolor,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
double myheight = MediaQuery.of(context).size.height;
|
double myheight = MediaQuery.of(context).size.height;
|
||||||
double mywidth = MediaQuery.of(context).size.width;
|
double mywidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child:
|
child: GestureDetector(
|
||||||
Container(
|
onTap: () {
|
||||||
height: myheight/9,
|
context.go('/DemoHome');
|
||||||
width: mywidth/4,
|
},
|
||||||
|
child: Container(
|
||||||
|
height: myheight / 9,
|
||||||
|
width: mywidth / 4,
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 8),
|
margin: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(color: bordercolor),
|
border: Border.all(color: bordercolor),
|
||||||
@ -452,7 +467,6 @@ class InfoCard extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
title,
|
||||||
//textAlign: TextAlign.center,
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@ -475,12 +489,13 @@ class InfoCard extends StatelessWidget {
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: textcolor ?? Colors.black
|
color: textcolor ?? Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -194,17 +194,39 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void _pickImage() async {
|
||||||
|
// final XFile? pickedFile =
|
||||||
|
// await _picker.pickImage(source: ImageSource.gallery);
|
||||||
|
// if (pickedFile != null) {
|
||||||
|
// setState(() {
|
||||||
|
// _profileImage = File(pickedFile.path);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Function to open the date picker
|
||||||
|
|
||||||
void _pickImage() async {
|
void _pickImage() async {
|
||||||
final XFile? pickedFile =
|
final XFile? pickedFile =
|
||||||
await _picker.pickImage(source: ImageSource.gallery);
|
await _picker.pickImage(source: ImageSource.gallery);
|
||||||
if (pickedFile != null) {
|
if (pickedFile != null) {
|
||||||
|
final String fileExtension =
|
||||||
|
pickedFile.path.split('.').last.toLowerCase();
|
||||||
|
if (fileExtension == 'jpg' ||
|
||||||
|
fileExtension == 'jpeg' ||
|
||||||
|
fileExtension == 'png' ||
|
||||||
|
fileExtension == "heic") {
|
||||||
setState(() {
|
setState(() {
|
||||||
_profileImage = File(pickedFile.path);
|
_profileImage = File(pickedFile.path);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Please select a JPG, JPEG, or PNG file.')),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to open the date picker
|
|
||||||
Future<void> _pickDate() async {
|
Future<void> _pickDate() async {
|
||||||
final DateTime today = DateTime.now();
|
final DateTime today = DateTime.now();
|
||||||
final DateTime initialDate = _selectedDate ??
|
final DateTime initialDate = _selectedDate ??
|
||||||
@ -398,7 +420,9 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
Text(
|
Text(
|
||||||
"User Name",
|
"User Name",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16, fontWeight: FontWeight.w500),
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -407,7 +431,7 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
controller: _usernameController,
|
controller: _usernameController,
|
||||||
focusNode: _focusNodes[0],
|
focusNode: _focusNodes[0],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: _showHints[0] ? 'Mohammad Hassan' : null,
|
// hintText: _showHints[0] ? 'Mohammad Hassan' : null,
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
@ -420,9 +444,11 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"E-mail",
|
"Email ID",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16, fontWeight: FontWeight.w500),
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -431,10 +457,7 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
controller: _emailController,
|
controller: _emailController,
|
||||||
focusNode: _focusNodes[1],
|
focusNode: _focusNodes[1],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: _showHints[1]
|
// hintText: _showHints[1]? 'mohammad.hassan@fcsc.gov.ae': null,
|
||||||
? 'mohammad.hassan@fcsc.gov.ae'
|
|
||||||
: null,
|
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
@ -446,9 +469,11 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Full Name",
|
"Full Name*",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16, fontWeight: FontWeight.w500),
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -471,7 +496,7 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
controller: _fullNameController,
|
controller: _fullNameController,
|
||||||
focusNode: _focusNodes[2],
|
focusNode: _focusNodes[2],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: _showHints[2] ? 'Mohammad' : null,
|
// hintText: _showHints[2] ? 'Mohammad' : null,
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
@ -490,7 +515,9 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
Text(
|
Text(
|
||||||
"Date of Birth*",
|
"Date of Birth*",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16, fontWeight: FontWeight.w500),
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -502,10 +529,8 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
hintText: _showHints[3]
|
// hintText: _showHints[3] ? 'Select your Date of Birth' : null,
|
||||||
? 'Select your Date of Birth'
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
: null,
|
|
||||||
//hintText: 'Select your Date of Birth',
|
|
||||||
suffixIcon: const Icon(Icons.arrow_drop_down_sharp),
|
suffixIcon: const Icon(Icons.arrow_drop_down_sharp),
|
||||||
enabled: !_isProfileCompleted,
|
enabled: !_isProfileCompleted,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -43,7 +43,9 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
|||||||
try {
|
try {
|
||||||
await _pb.admins
|
await _pb.admins
|
||||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||||
final result = await _pb.collection('users').getFullList();
|
final result = await _pb.collection('users').getFullList(
|
||||||
|
filter: 'role="user"',
|
||||||
|
);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
userData = result.map((record) {
|
userData = result.map((record) {
|
||||||
|
|||||||
@ -26,7 +26,6 @@ class _FAQPageState extends State<FAQPage> {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
// color: Colors.white, // Background color// Optional padding around the text
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'HERE ARE SOME COMMON QUESTIONS ABOUT THE FEDERAL COMPETITIVENESS AND STATISTICS CENTRE (FCSC) MOBILE APPLICATION:',
|
'HERE ARE SOME COMMON QUESTIONS ABOUT THE FEDERAL COMPETITIVENESS AND STATISTICS CENTRE (FCSC) MOBILE APPLICATION:',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
|||||||
@ -1,23 +1,21 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/custom_text.dart';
|
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
||||||
|
|
||||||
|
import 'custom_text.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UsingFeatures extends StatelessWidget {
|
class UsingFeatures extends StatelessWidget {
|
||||||
|
|
||||||
final List<Map<String, dynamic>> contentList = [
|
final List<Map<String, dynamic>> contentList = [
|
||||||
{
|
{
|
||||||
'text': '1.Comprehensive Statistics',
|
"text": "1.Data-Driven Insights:",
|
||||||
'fontSize': 16.0,
|
"fontSize": 16.0,
|
||||||
'color': Color(0xFF414042),
|
"color": Color(0xFF414042),
|
||||||
"fontWeight": FontWeight.bold,
|
"fontWeight": FontWeight.bold,
|
||||||
"isBulletPoint": false,
|
"isBulletPoint": false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'text': 'Gain insights into vital statistics across categories like Economy, Environment, Social, and more.Explore detailed data, smart metrics, and interactive graphical representations.',
|
"text": "1.Access detailed datasets across categories such as Economy, Environment, Social, and more.Explore statistics presented as smart metrics, graphs, and charts for better understanding.",
|
||||||
"fontSize": 13.0,
|
"fontSize": 13.0,
|
||||||
"color": Color(0xFF898C81),
|
"color": Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
"fontWeight": FontWeight.normal,
|
||||||
@ -38,7 +36,7 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
"isBulletPoint": false,
|
"isBulletPoint": false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "3.Personalized Experience:",
|
"text": "3.Interactive Visualizations:",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF414042),
|
"color": Color(0xFF414042),
|
||||||
"fontWeight": FontWeight.bold,
|
"fontWeight": FontWeight.bold,
|
||||||
@ -46,24 +44,33 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"text": "Bookmark important metrics for quick access.",
|
"text": "View trends and relationships with interactive graphs and charts, including bar graphs, line charts, and more.",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"height":0.1,
|
|
||||||
"color": Color(0xFF898C81),
|
"color": Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
"fontWeight": FontWeight.normal,
|
||||||
"isBulletPoint": true,
|
"isBulletPoint": true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "Edit your profile to keep your information updated.",
|
"text": "Secure User Access:",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"height":1.0,
|
"height":1.0,
|
||||||
"color": Color(0xFF898C81),
|
"color": Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
"fontWeight": FontWeight.bold,
|
||||||
"isBulletPoint": true,
|
"isBulletPoint": true,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"text": "4.Interactive Graphs and Metrics:",
|
"text": "4.Available only to registered users whose accounts have been approved by an admin.Login ensures secure access to sensitive statistical information.",
|
||||||
|
"fontSize": 14.0,
|
||||||
|
"color": Color(0xFF414042),
|
||||||
|
"fontWeight": FontWeight.normal,
|
||||||
|
"isBulletPoint": false,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "5.Profile Customization:",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF414042),
|
"color": Color(0xFF414042),
|
||||||
"fontWeight": FontWeight.bold,
|
"fontWeight": FontWeight.bold,
|
||||||
@ -71,7 +78,7 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"text": "Visualize trends and insights with well-designed, interactive charts and graphs that make data easy to understand.",
|
"text": "Update your profile details, such as name, password, and region, to personalize your experience.",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF898C81),
|
"color": Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
"fontWeight": FontWeight.normal,
|
||||||
@ -79,7 +86,7 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"text": "5.Log-in Access Mode:",
|
"text": "6.Bookmark:",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF414042),
|
"color": Color(0xFF414042),
|
||||||
"fontWeight": FontWeight.bold,
|
"fontWeight": FontWeight.bold,
|
||||||
@ -87,7 +94,7 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"text": "Access advanced features like bookmarks and profile customization.",
|
"text": "Save frequently accessed metrics and datasets for quick reference via the Bookmarks section.",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF898C81),
|
"color": Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
"fontWeight": FontWeight.normal,
|
||||||
@ -95,7 +102,7 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"text": "6.Dual Language Support:",
|
"text": "7.Bilingual Support:",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF414042),
|
"color": Color(0xFF414042),
|
||||||
"fontWeight": FontWeight.bold,
|
"fontWeight": FontWeight.bold,
|
||||||
@ -103,7 +110,7 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"text": "Toggle between English and Arabic for a seamless bilingual experience.",
|
"text": "Toggle between English and Arabic for ease of use.",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF898C81),
|
"color": Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
"fontWeight": FontWeight.normal,
|
||||||
@ -551,8 +558,8 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
"text": "Select Confirm to save the changes or Cancel to go back",
|
"text": "Select Confirm to save the changes or Cancel to go back",
|
||||||
"fontSize": 14.0,
|
"fontSize": 14.0,
|
||||||
"color": Color(0xFF898C81),
|
"color": Color(0xFF898C81),
|
||||||
'fontWeight': FontWeight.normal,
|
"fontWeight": FontWeight.normal,
|
||||||
'isBulletPoint': true,
|
"isBulletPoint": true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -561,8 +568,7 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseScaffold(
|
return BaseScaffold( title: Text('Key Features'),
|
||||||
title:Text ('Key Features'),
|
|
||||||
body: Scrollbar(
|
body: Scrollbar(
|
||||||
thumbVisibility: true,
|
thumbVisibility: true,
|
||||||
thickness: 6,
|
thickness: 6,
|
||||||
@ -575,13 +581,12 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
// color: Colors.white,
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'FEATURES',
|
"FEATURES",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Color(0xFF265E84), // Text color
|
color: Color(0xFF265E84), // Text color
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -595,19 +600,18 @@ class UsingFeatures extends StatelessWidget {
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = contentList[index];
|
final item = contentList[index];
|
||||||
return CustomContainer(
|
return CustomContainer(
|
||||||
text: item['text'],
|
text: item["text"],
|
||||||
fontSize: item['fontSize'],
|
fontSize: item["fontSize"],
|
||||||
color: item['color'],
|
color: item["color"],
|
||||||
fontWeight: item['fontWeight'],
|
fontWeight: item["fontWeight"],
|
||||||
height:item['height'],
|
height:item["height"],
|
||||||
isBulletPoint: item['isBulletPoint'] ?? false,
|
isBulletPoint: item["isBulletPoint"] ?? false,
|
||||||
textDecoration: item['textDecoration'] ?? TextDecoration.none,
|
textDecoration: item["textDecoration"] ?? TextDecoration.none,
|
||||||
decorationColor: item['decorationColor'],
|
decorationColor: item["decorationColor"],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -15,53 +15,53 @@ class GettingStarted extends StatelessWidget {
|
|||||||
|
|
||||||
final List<Map<String, dynamic>> contentList = [
|
final List<Map<String, dynamic>> contentList = [
|
||||||
{
|
{
|
||||||
"text": "This app provides a centralized platform to access key statistical data and insights about the UAE, empoweringusers with accurate and up-to-date information on various sectors.",
|
'text': 'This app provides a centralized platform to access key statistical data and insights about the UAE, empoweringusers with accurate and up-to-date information on various sectors.',
|
||||||
"fontSize": 16.0,
|
'fontSize': 16.0,
|
||||||
"color": Color(0xFF898C81),
|
'color': Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
'fontWeight': FontWeight.normal,
|
||||||
"isBulletPoint": false,
|
'isBulletPoint': false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "How to Get Started",
|
'text': 'How to Get Started',
|
||||||
"fontSize": 18.0,
|
'fontSize': 18.0,
|
||||||
"color": Color(0xFF414042),
|
'color': Color(0xFF414042),
|
||||||
"fontWeight": FontWeight.w600,
|
'fontWeight': FontWeight.w600,
|
||||||
"isBulletPoint": false,
|
'isBulletPoint': false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "1.Download the app from the App Store or Google Play Store.",
|
'text': '1.Download the app from the App Store or Google Play Store.',
|
||||||
"fontSize": 14.0,
|
'fontSize': 14.0,
|
||||||
"color": Color(0xFF898C81),
|
'color': Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
'fontWeight': FontWeight.normal,
|
||||||
"isBulletPoint": false,
|
'isBulletPoint': false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "2.Log in to unlock advanced features or continue as a guest.",
|
'text': '2.Log in to unlock advanced features or continue as a guest.',
|
||||||
"fontSize": 14.0,
|
'fontSize': 14.0,
|
||||||
"color": Color(0xFF898C81),
|
'color': Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
'fontWeight': FontWeight.normal,
|
||||||
"isBulletPoint": false,
|
'isBulletPoint': false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "3.Navigate through categories, explore metrics, and bookmark essential information.",
|
'text': '3.Navigate through categories, explore metrics, and bookmark essential information.',
|
||||||
"fontSize": 14.0,
|
'fontSize': 14.0,
|
||||||
"color": Color(0xFF898C81),
|
'color': Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
'fontWeight': FontWeight.normal,
|
||||||
"isBulletPoint": false,
|
'isBulletPoint': false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "Stay Updated",
|
'text': 'Stay Updated',
|
||||||
"fontSize": 18.0,
|
'fontSize': 18.0,
|
||||||
"color": Color(0xFF414042),
|
'color': Color(0xFF414042),
|
||||||
"fontWeight": FontWeight.bold,
|
'fontWeight': FontWeight.bold,
|
||||||
"isBulletPoint": false,
|
'isBulletPoint': false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "The app regularly updates datasets and features to reflect the latest information. Notifications will alert you about new data or improvements.",
|
'text': 'The app regularly updates datasets and features to reflect the latest information. Notifications will alert you about new data or improvements.',
|
||||||
"fontSize": 14.0,
|
'fontSize': 14.0,
|
||||||
"color": Color(0xFF898C81),
|
'color': Color(0xFF898C81),
|
||||||
"fontWeight": FontWeight.normal,
|
'fontWeight': FontWeight.normal,
|
||||||
"isBulletPoint": false,
|
'isBulletPoint': false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -99,14 +99,14 @@ class GettingStarted extends StatelessWidget {
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = contentList[index];
|
final item = contentList[index];
|
||||||
return CustomContainer(
|
return CustomContainer(
|
||||||
text: item["text"],
|
text: item['text'],
|
||||||
fontSize: item["fontSize"]?? 20,
|
fontSize: item['fontSize']?? 20,
|
||||||
color: item["color"],
|
color: item['color'],
|
||||||
fontWeight: item["fontWeight"],
|
fontWeight: item['fontWeight'],
|
||||||
height:item["height"],
|
height:item['height'],
|
||||||
isBulletPoint: item["isBulletPoint"] ?? false,
|
isBulletPoint: item['isBulletPoint'] ?? false,
|
||||||
textDecoration: item["textDecoration"] ?? TextDecoration.none,
|
textDecoration: item['textDecoration'] ?? TextDecoration.none,
|
||||||
decorationColor: item["decorationColor"],
|
decorationColor: item['decorationColor'],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -146,7 +146,7 @@ class GettingStarted extends StatelessWidget {
|
|||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
child: Center( child: fcscBanner,),
|
child: Center( child: fcscBanner,),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,110 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class ExpandableRichText extends StatefulWidget {
|
|
||||||
final List<TextSpan> textSpans;
|
|
||||||
final int maxLines;
|
|
||||||
final TextStyle? defaultStyle;
|
|
||||||
|
|
||||||
ExpandableRichText({
|
|
||||||
required this.textSpans,
|
|
||||||
this.maxLines = 0,
|
|
||||||
this.defaultStyle,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
_ExpandableRichTextState createState() => _ExpandableRichTextState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ExpandableRichTextState extends State<ExpandableRichText> {
|
|
||||||
bool isExpanded = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
|
||||||
final span = TextSpan(
|
|
||||||
children: widget.textSpans,
|
|
||||||
style: widget.defaultStyle,
|
|
||||||
);
|
|
||||||
|
|
||||||
final textPainter = TextPainter(
|
|
||||||
text: span,
|
|
||||||
maxLines: widget.maxLines,
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
);
|
|
||||||
|
|
||||||
textPainter.layout(maxWidth: constraints.maxWidth);
|
|
||||||
|
|
||||||
final isOverflowing = textPainter.didExceedMaxLines;
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text.rich(
|
|
||||||
span,
|
|
||||||
maxLines: isExpanded ? null : widget.maxLines,
|
|
||||||
overflow: isExpanded ? null : TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
if (isOverflowing)
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
isExpanded = !isExpanded;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
isExpanded ? 'View less' : 'View more',
|
|
||||||
style: TextStyle(
|
|
||||||
|
|
||||||
color: Color(0xFF265E84),
|
|
||||||
decoration: TextDecoration.underline,
|
|
||||||
decorationColor: Color(0xFF265E84),
|
|
||||||
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper method to build `Text.rich`
|
|
||||||
Widget buildRichText(List<TextSpan> textSpans) {
|
|
||||||
return Text.rich(
|
|
||||||
TextSpan(children: textSpans),
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper method to create custom `TextSpan`
|
|
||||||
TextSpan createTextSpan(
|
|
||||||
String text, {
|
|
||||||
double? fontSize,
|
|
||||||
Color color = const Color(0xFF898C81),
|
|
||||||
FontWeight fontWeight = FontWeight.w500,
|
|
||||||
double? height,
|
|
||||||
double defaultFontSize = 14,
|
|
||||||
TextDecoration textDecoration = TextDecoration.none,
|
|
||||||
Color? decorationColor,
|
|
||||||
double spacingTop = 0.0, // Custom top spacing
|
|
||||||
double spacingBottom = 0.0,
|
|
||||||
}) {
|
|
||||||
String spacedText = '${'\n' * spacingTop.toInt()}$text${'\n' * spacingBottom.toInt()}';
|
|
||||||
|
|
||||||
return TextSpan(
|
|
||||||
text: spacedText,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: fontSize ?? defaultFontSize,
|
|
||||||
color: color,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
height: height,
|
|
||||||
decoration: textDecoration,
|
|
||||||
decorationColor: decorationColor ?? color,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ class BaseScaffold extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: title, actions: [
|
appBar: AppBar(title: title, actions: [
|
||||||
IconButton(onPressed: () {}, icon: Icon(Icons.toggle_off_outlined)),
|
IconButton(onPressed: () {}, icon: Icon(Icons.toggle_off_outlined)),
|
||||||
],),
|
]),
|
||||||
drawer: Drawer(
|
drawer: Drawer(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
@ -39,19 +39,19 @@ class BaseScaffold extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: mywidth / 8,
|
width: mywidth / 8,
|
||||||
child: Image(
|
child: Image(
|
||||||
image: AssetImage('assets/logos/fcsc.png'),),),
|
image: AssetImage('assets/logos/fcsc.png'))),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Divider(),
|
Divider(),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => context.go('/Profile'),
|
onTap: () => context.go('/editProfile'),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: mywidth / 8,
|
width: mywidth / 8,
|
||||||
child: Image(
|
child: Image(
|
||||||
image: AssetImage(
|
image: AssetImage(
|
||||||
'assets/edit_profile/profile.png',),),),
|
'assets/edit_profile/profile.png'))),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: mywidth / 20,
|
width: mywidth / 20,
|
||||||
),
|
),
|
||||||
@ -59,12 +59,12 @@ class BaseScaffold extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('Mohammad'),
|
Text('Mohammad'),
|
||||||
Text('Mohammad@fcsc.com'),
|
Text('Mohammad@fcsc.com')
|
||||||
|
],
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
)
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -73,19 +73,10 @@ class BaseScaffold extends StatelessWidget {
|
|||||||
height: myheight / 15,
|
height: myheight / 15,
|
||||||
width: mywidth / 15,
|
width: mywidth / 15,
|
||||||
child: Image(
|
child: Image(
|
||||||
image: AssetImage('assets/icons/drawer/message.png'),),),
|
image: AssetImage('assets/icons/drawer/message.png'))),
|
||||||
title: Text('Feedback'),
|
title: Text('Feedback'),
|
||||||
onTap: () => context.go('/feedback'),
|
onTap: () => context.go('/feedback'),
|
||||||
),
|
),
|
||||||
ListTile(
|
|
||||||
leading: SizedBox(
|
|
||||||
height: myheight / 15,
|
|
||||||
width: mywidth / 15,
|
|
||||||
child: Image(
|
|
||||||
image: AssetImage('assets/icons/drawer/book.png'),),),
|
|
||||||
title: Text('User Guide'),
|
|
||||||
onTap: () => context.go('/user-guide'),
|
|
||||||
),
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: SizedBox(
|
leading: SizedBox(
|
||||||
height: myheight / 15,
|
height: myheight / 15,
|
||||||
@ -95,6 +86,16 @@ class BaseScaffold extends StatelessWidget {
|
|||||||
title: Text('Manage User'),
|
title: Text('Manage User'),
|
||||||
onTap: () => context.go('/manageuser'),
|
onTap: () => context.go('/manageuser'),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
ListTile(
|
||||||
|
leading: SizedBox(
|
||||||
|
height: myheight / 15,
|
||||||
|
width: mywidth / 15,
|
||||||
|
child: Image(
|
||||||
|
image: AssetImage('assets/icons/drawer/book.png'))),
|
||||||
|
title: Text('User Guide'),
|
||||||
|
onTap: () => context.go('/user-guide'),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
78
pubspec.lock
78
pubspec.lock
@ -130,10 +130,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.9.2"
|
version: "8.9.3"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -443,10 +443,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_plugin_android_lifecycle
|
name: flutter_plugin_android_lifecycle
|
||||||
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
|
sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.23"
|
version: "2.0.24"
|
||||||
flutter_rating_bar:
|
flutter_rating_bar:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -525,10 +525,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fluttertoast
|
name: fluttertoast
|
||||||
sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc"
|
sha256: "24467dc20bbe49fd63e57d8e190798c4d22cbbdac30e54209d153a15273721d1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.2.8"
|
version: "8.2.10"
|
||||||
freezed:
|
freezed:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -557,10 +557,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: get_it
|
name: get_it
|
||||||
sha256: c49895c1ecb0ee2a0ec568d39de882e2c299ba26355aa6744ab1001f98cebd15
|
sha256: f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.2"
|
version: "8.0.3"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -621,10 +621,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_multi_server
|
name: http_multi_server
|
||||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.1"
|
version: "3.2.2"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -653,10 +653,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image_picker_android
|
name: image_picker_android
|
||||||
sha256: fa8141602fde3f7e2f81dbf043613eb44dfa325fa0bcf93c0f142c9f7a2c193e
|
sha256: aa6f1280b670861ac45220cc95adc59bb6ae130259d36f980ccb62220dc5e59f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.12+18"
|
version: "0.8.12+19"
|
||||||
image_picker_for_web:
|
image_picker_for_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -841,6 +841,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.16+1"
|
version: "0.12.16+1"
|
||||||
|
material_charts:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: material_charts
|
||||||
|
sha256: ada5af96e9cdd9888c1931eaf307e6693408584ca0de1b1c795f9862590f9fcf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.25"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -997,10 +1005,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.4.0"
|
||||||
recase:
|
recase:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1076,42 +1084,42 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: share_plus
|
name: share_plus
|
||||||
sha256: "9c9bafd4060728d7cdb2464c341743adbd79d327cb067ec7afb64583540b47c8"
|
sha256: "6327c3f233729374d0abaafd61f6846115b2a481b4feddd8534211dc10659400"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.1.2"
|
version: "10.1.3"
|
||||||
share_plus_platform_interface:
|
share_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: share_plus_platform_interface
|
name: share_plus_platform_interface
|
||||||
sha256: c57c0bbfec7142e3a0f55633be504b796af72e60e3c791b44d5a017b985f7a48
|
sha256: cc012a23fc2d479854e6c80150696c4a5f5bb62cb89af4de1c505cf78d0a5d0b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.1"
|
version: "5.0.2"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82"
|
sha256: "3c7e73920c694a436afaf65ab60ce3453d91f84208d761fbd83fc21182134d93"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.3"
|
version: "2.3.4"
|
||||||
shared_preferences_android:
|
shared_preferences_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549"
|
sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.4"
|
version: "2.4.0"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_foundation
|
name: shared_preferences_foundation
|
||||||
sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d"
|
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.3"
|
version: "2.5.4"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1184,10 +1192,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_helper
|
name: source_helper
|
||||||
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
|
sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.4"
|
version: "1.3.5"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1232,10 +1240,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_transform
|
name: stream_transform
|
||||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1408,10 +1416,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: watcher
|
name: watcher
|
||||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1448,10 +1456,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: webview_flutter_android
|
name: webview_flutter_android
|
||||||
sha256: "285cedfd9441267f6cca8843458620b5fda1af75b04f5818d0441acda5d7df19"
|
sha256: "3d535126f7244871542b2f0b0fcf94629c9a14883250461f9abe1a6644c1c379"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.2.0"
|
||||||
webview_flutter_platform_interface:
|
webview_flutter_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1496,10 +1504,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.5.0 <4.0.0"
|
dart: ">=3.5.2 <4.0.0"
|
||||||
flutter: ">=3.24.0"
|
flutter: ">=3.24.0"
|
||||||
|
|||||||
@ -54,7 +54,8 @@ dependencies:
|
|||||||
provider: ^6.1.2
|
provider: ^6.1.2
|
||||||
mailer: ^6.2.0
|
mailer: ^6.2.0
|
||||||
image_picker: ^1.1.2
|
image_picker: ^1.1.2
|
||||||
syncfusion_flutter_charts: ^28.1.33
|
syncfusion_flutter_charts: 28.1.33
|
||||||
|
material_charts: ^0.0.23
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
fading_edge_scrollview: ^4.1.1
|
fading_edge_scrollview: ^4.1.1
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user