diff --git a/.run/main.dart.run.xml b/.run/main.dart.run.xml
index 4767aff8..4a58a7c9 100644
--- a/.run/main.dart.run.xml
+++ b/.run/main.dart.run.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart
index 62b87e6f..cdfe3b13 100644
--- a/lib/config/my_router.dart
+++ b/lib/config/my_router.dart
@@ -299,6 +299,7 @@ import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.
import '../domain/use_cases/preferences_use_case.dart';
import '../presentation/Screens/auth_verification/changepassword.dart';
import '../presentation/Screens/auth_verification/confirm_password.dart';
+import '../presentation/Screens/auth_verification/create_new_pw.dart';
import '../presentation/Screens/auth_verification/otp_verification.dart';
import '../presentation/Screens/profilepage.dart';
import '../presentation/routes/auth_routes/login_route.dart';
@@ -333,6 +334,14 @@ final GoRouter router = GoRouter(
userId: '',
),
),
+ GoRoute(
+ path: '/createNewPw/:userId/:email',
+ builder: (context, state) {
+ final userId = state.pathParameters['userId']!;
+ final email = state.pathParameters['email']!;
+ return CreateNewPw(userId: userId, email: email);
+ },
+ ),
GoRoute(
path: '/confirmpasswd',
builder: (context, state) => ConfirmPassword(
diff --git a/lib/presentation/Screens/auth_verification/create_new_pw.dart b/lib/presentation/Screens/auth_verification/create_new_pw.dart
new file mode 100644
index 00000000..196b760c
--- /dev/null
+++ b/lib/presentation/Screens/auth_verification/create_new_pw.dart
@@ -0,0 +1,387 @@
+import 'package:external_repos/external_repos.dart';
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+import 'package:pocketbase/pocketbase.dart';
+import 'package:uae_stat/config/my_router.dart';
+import 'package:uae_stat/domain/use_cases/language.dart';
+import 'package:uae_stat/presentation/Screens/profilepage.dart';
+import 'package:uae_stat/presentation/components/space.dart';
+
+import '../../../config/my_theme.dart';
+
+class CreateNewPw extends StatefulWidget {
+ final String userId;
+ final String email;
+ const CreateNewPw({Key? key, required this.userId, required this.email});
+
+ @override
+ State createState() => _CreateNewPwState();
+}
+
+class _CreateNewPwState extends State {
+ final _pb = PocketBase('https://pb.venbait.in');
+ final _formKey = GlobalKey();
+ bool _obscureOldPassword = true;
+ bool _obscureNewPassword = true;
+ bool _obscureConfirmPassword = true;
+ bool _isPasswordUpdated = false; // Variable to toggle UI
+
+ String? _oldPassword;
+ String? _newPassword;
+ String? _confirmPassword;
+
+ String? _validateOldPassword(String? value) {
+ if (value == null || value.isEmpty) {
+ return 'Old password is required';
+ }
+ return null;
+ }
+
+ String? _validateNewPassword(String? value) {
+ if (value == null || value.isEmpty) {
+ return 'New password is required';
+ } else if (value.length < 6) {
+ return 'Password must be at least 6 characters';
+ } else if (value == _oldPassword) {
+ return 'New password must not be the same as the old password';
+ }
+ _newPassword = value; // Store for validation
+ return null;
+ }
+
+ String? _validateConfirmPassword(String? value) {
+ if (value == null || value.isEmpty) {
+ return 'Confirm password is required';
+ } else if (value != _newPassword) {
+ return 'Passwords do not match';
+ }
+ _confirmPassword = value;
+ return null;
+ }
+
+ Future verifyUserPassword(String email, String password) async {
+ try {
+ // Attempt to authenticate the user with email and password
+ final authResponse =
+ await _pb.collection('users').authWithPassword(email, password);
+
+ if (authResponse != null) {
+ print('Password match successful for email: $email');
+ return true; // Password matches
+ }
+ } catch (e) {
+ // Authentication failed, password does not match
+ print('Error verifying password: $e');
+ }
+
+ return false; // Password does not match
+ }
+
+ Future updatePassword(
+ String userId, String oldPassword, String newPassword) async {
+ try {
+ // Authenticate as admin
+ final adminAuth = await _pb.admins
+ .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
+ final token = adminAuth.token;
+
+ final headers = {
+ 'Authorization': 'Bearer $token',
+ };
+
+ bool isPasswordValid =
+ await verifyUserPassword(widget.email, oldPassword);
+
+ print(isPasswordValid);
+
+ if (isPasswordValid) {
+ // Update password
+ await _pb.collection('users').update(
+ userId,
+ body: {
+ 'password': newPassword,
+ 'passwordConfirm': newPassword,
+ },
+ headers: headers,
+ );
+
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Password updated successfully.'),
+ backgroundColor: Colors.green,
+ ),
+ );
+
+ setState(() {
+ _isPasswordUpdated = true; // Toggle UI on success
+ });
+
+ // Navigator.push(
+ // context,
+ // MaterialPageRoute(
+ // builder: (context) => ProfileScreen(userId: userId)),
+ // );
+ } else {
+ setState(() {
+ _formKey.currentState?.validate();
+ });
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Your old password is incorrect.'),
+ backgroundColor: Colors.red,
+ ),
+ );
+ return;
+ }
+ } catch (e) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Failed to update password: $e'),
+ backgroundColor: Colors.red,
+ ),
+ );
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ double screenHeight = MediaQuery.of(context).size.height;
+ double screenWidth = MediaQuery.of(context).size.width;
+
+ return Scaffold(
+ backgroundColor: Colors.white,
+ body: SingleChildScrollView(
+ child: SafeArea(
+ child: _isPasswordUpdated
+ ? _buildSuccessContent(screenHeight, screenWidth)
+ : _buildPasswordForm(screenHeight, screenWidth),
+ ),
+ ),
+ );
+ }
+
+ Widget _buildPasswordForm(double screenHeight, double screenWidth) {
+ return Form(
+ key: _formKey,
+ child: Padding(
+ padding: const EdgeInsets.all(24.0),
+ child: Column(
+ children: [
+ SizedBox(height: screenHeight / 6),
+ Text(
+ "Create New Password",
+ style: TextStyle(
+ fontSize: 24,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: screenHeight / 35),
+ TextFormField(
+ obscureText: _obscureOldPassword,
+ decoration: InputDecoration(
+ hintText: 'Enter old password',
+ prefixIcon: Icon(Icons.lock, color: Colors.blue),
+ suffixIcon: IconButton(
+ icon: Icon(
+ _obscureOldPassword
+ ? Icons.visibility
+ : Icons.visibility_off,
+ color: Colors.blue,
+ ),
+ onPressed: () {
+ setState(() {
+ _obscureOldPassword = !_obscureOldPassword;
+ });
+ },
+ ),
+ border: OutlineInputBorder(),
+ ),
+ validator: _validateOldPassword,
+ onChanged: (value) => _oldPassword = value,
+ ),
+ SizedBox(height: screenHeight / 35),
+ TextFormField(
+ obscureText: _obscureNewPassword,
+ decoration: InputDecoration(
+ hintText: 'Enter new password',
+ prefixIcon: Icon(Icons.lock, color: Colors.blue),
+ suffixIcon: IconButton(
+ icon: Icon(
+ _obscureNewPassword
+ ? Icons.visibility
+ : Icons.visibility_off,
+ color: Colors.blue,
+ ),
+ onPressed: () {
+ setState(() {
+ _obscureNewPassword = !_obscureNewPassword;
+ });
+ },
+ ),
+ border: OutlineInputBorder(),
+ ),
+ validator: _validateNewPassword,
+ ),
+ SizedBox(height: screenHeight / 35),
+ TextFormField(
+ obscureText: _obscureConfirmPassword,
+ decoration: InputDecoration(
+ hintText: 'Confirm new password',
+ prefixIcon: Icon(Icons.lock, color: Colors.blue),
+ suffixIcon: IconButton(
+ icon: Icon(
+ _obscureConfirmPassword
+ ? Icons.visibility
+ : Icons.visibility_off,
+ color: Colors.blue,
+ ),
+ onPressed: () {
+ setState(() {
+ _obscureConfirmPassword = !_obscureConfirmPassword;
+ });
+ },
+ ),
+ border: OutlineInputBorder(),
+ ),
+ validator: _validateConfirmPassword,
+ ),
+ SizedBox(height: screenHeight / 35),
+ SizedBox(
+ width: screenWidth / 1.1,
+ child: ElevatedButton(
+ onPressed: () async {
+ if ((_formKey.currentState?.validate() ?? false)) {
+ await updatePassword(
+ widget.userId,
+ _oldPassword ?? '',
+ _newPassword ?? '',
+ );
+ }
+ },
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Colors.brown[300],
+ padding: EdgeInsets.symmetric(horizontal: 80, vertical: 16),
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ ),
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ "Save",
+ style: TextStyle(fontSize: 18, color: Colors.white),
+ ),
+ SizedBox(width: 2),
+ Icon(
+ Icons.arrow_forward_ios,
+ color: Colors.white38,
+ size: 18,
+ ),
+ ],
+ ),
+ ),
+ ),
+ SizedBox(height: screenHeight / 5),
+ Center(
+ child: Container(
+ height: screenHeight / 8,
+ width: screenWidth / 2,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage("assets/splash_screen/logo.png"),
+ fit: BoxFit.fill,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget _buildSuccessContent(double screenHeight, double screenWidth) {
+ return Padding(
+ padding: const EdgeInsets.all(20.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ SizedBox(height: screenHeight / 8),
+ Icon(Icons.check_circle_outlined, color: Color(0xFF8AC681), size: 80),
+ SizedBox(height: 20),
+ Text(
+ "Password Changed Successfully",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w500,
+ color: Color(0xFF414042),
+ ),
+ ),
+ SizedBox(height: 10),
+ ElevatedButton(
+ onPressed: () async {
+ context.go('/');
+ },
+ style: ButtonStyle(
+ shape: WidgetStatePropertyAll(
+ RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ ),
+ ),
+ padding: const WidgetStatePropertyAll(
+ EdgeInsets.symmetric(vertical: 10.5),
+ ),
+ textStyle: WidgetStatePropertyAll(
+ TextStyle(
+ fontFamily: context.translate(
+ 'Roboto',
+ 'NotoKufi',
+ ),
+ fontSize: 16,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ backgroundColor: WidgetStatePropertyAll(
+ MyTheme.topicColor(IndicatorTopic.social),
+ ),
+ // surfaceTintColor: MaterialStatePropertyAll(
+ // MyTheme.economy[800],
+ // ),
+ foregroundColor: const WidgetStatePropertyAll(
+ Colors.white,
+ ),
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ context.translate(
+ 'Login',
+ 'تسجيل الدخول',
+ ),
+ ),
+ 6.horizontalSpace,
+ const Icon(Icons.chevron_right_outlined),
+ ],
+ ),
+ ),
+ SizedBox(height: screenHeight / 5),
+ Center(
+ child: Container(
+ height: screenHeight / 8,
+ width: screenWidth / 2,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage("assets/splash_screen/logo.png"),
+ fit: BoxFit.fill,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/Screens/auth_verification/registration.dart b/lib/presentation/Screens/auth_verification/registration.dart
index 46339c76..97204028 100644
--- a/lib/presentation/Screens/auth_verification/registration.dart
+++ b/lib/presentation/Screens/auth_verification/registration.dart
@@ -207,7 +207,6 @@ class _RegisterScreenState extends State {
registrationSuccess = true;
registrationFailed = false; // Show success message on success
});
- context.go('/profile');
// Navigate to ProfileScreen after successful registration
// Navigator.pushReplacement(
@@ -241,414 +240,8 @@ class _RegisterScreenState extends State {
double screenheight = MediaQuery.of(context).size.height;
double screenwidth = MediaQuery.of(context).size.width;
-
- return Scaffold(
- backgroundColor: Colors.white,
- body: registrationSuccess
- ? registration_success(context)
- : registrationFailed
- ? registration_failed(context)
- : Scaffold(
- body: Padding(
- padding: const EdgeInsets.all(20.0),
- child: Form(
- key: _formKey,
- child: SingleChildScrollView(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- SizedBox(height: screenheight / 6),
- Text(
- 'Register',
- style: TextStyle(
- fontSize: 32, fontWeight: FontWeight.w400),
- ),
- SizedBox(height: 10),
- Text('Please enter your details'),
-
- SizedBox(height: 20),
- // Display this if registration is pending approval
- TextFormField(
- controller: _usernameController,
- focusNode: _focusNodes[0],
- decoration: InputDecoration(
- hintText: _showHints[0] ? 'Username' : null,
- prefixIcon: Icon(
- Icons.person,
- color: Colors.blue,
- ),
- border: OutlineInputBorder(),
- counterText: '',
- ),
- validator: _validateUsername,
- maxLength:
- 40, // Set the maximum length to 20 characters
- maxLengthEnforcement: MaxLengthEnforcement.enforced,
- ),
- SizedBox(height: 15),
- TextFormField(
- controller: _emailController,
- focusNode: _focusNodes[1],
- decoration: InputDecoration(
- // hintText: 'Enter your email',
- hintText:
- _showHints[1] ? 'Enter your email' : null,
- prefixIcon: Icon(
- Icons.email,
- color: Colors.blue,
- ),
- border: OutlineInputBorder(),
- counterText: '',
- ),
- validator: _validateEmail,
- maxLength: 320,
- maxLengthEnforcement: MaxLengthEnforcement.enforced,
- inputFormatters: [
- LengthLimitingTextInputFormatter(
- 320), // Limit to 320 characters
- ],
- ),
- SizedBox(height: 15),
- TextFormField(
- controller: _passwordController,
- focusNode: _focusNodes[2],
- obscureText: _obscurePassword,
- decoration: InputDecoration(
- hintText:
- _showHints[2] ? 'Enter your password' : null,
- prefixIcon: Icon(
- Icons.lock,
- color: Colors.blue,
- ),
- suffixIcon: IconButton(
- icon: Icon(
- _obscurePassword
- ? Icons.visibility
- : Icons.visibility_off,
- color: Colors.blue,
- ),
- onPressed: () {
- setState(() {
- _obscurePassword = !_obscurePassword;
- });
- },
- ),
- border: OutlineInputBorder(),
- counterText: '',
- ),
- validator: _validatePassword,
- maxLength: 40,
- maxLengthEnforcement: MaxLengthEnforcement.enforced,
- ),
- SizedBox(height: 15),
- TextFormField(
- controller: _confirmpasswordController,
- focusNode: _focusNodes[3],
- obscureText: _obscureConfirmPassword,
- decoration: InputDecoration(
- hintText:
- _showHints[3] ? 'Confirm password' : null,
- prefixIcon: Icon(
- Icons.lock,
- color: Colors.blue,
- ),
- suffixIcon: IconButton(
- icon: Icon(
- _obscureConfirmPassword
- ? Icons.visibility
- : Icons.visibility_off,
- color: Colors.blue,
- ),
- onPressed: () {
- setState(() {
- _obscureConfirmPassword =
- !_obscureConfirmPassword;
- });
- },
- ),
- border: OutlineInputBorder(),
- counterText: '',
- ),
- validator: _validateConfirmPassword,
- maxLength: 40,
- maxLengthEnforcement: MaxLengthEnforcement.enforced,
- inputFormatters: [
- LengthLimitingTextInputFormatter(
- 64), // Limit to 40 characters
- ],
- ),
- SizedBox(height: 10),
- Row(
- children: [
- Checkbox(
- value: isChecked,
- onChanged: (value) {
- setState(() {
- isChecked = value ?? false;
- showError = false;
- });
- },
- side: BorderSide(
- color: showError ? Colors.red : Colors.grey,
- width: 1.5,
- ),
- ),
- Expanded(
- child: Text.rich(
- TextSpan(
- text: 'I agree to ',
- children: [
- TextSpan(
- text: 'Terms & Conditions',
- style: TextStyle(color: Colors.blue),
- ),
- TextSpan(text: ' and '),
- TextSpan(
- text: 'Privacy Policy',
- style: TextStyle(color: Colors.blue),
- ),
- ],
- ),
- ),
- ),
- ],
- ),
- if (showError)
- Row(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- Padding(
- padding: const EdgeInsets.only(left: 10.0),
- child: Text(
- 'Please agree to terms and conditions.',
- style: TextStyle(
- color: Colors.red[700],
- fontSize: 12,
- ),
- ),
- ),
- ],
- ),
- SizedBox(height: 20),
- SizedBox(
- width: screenwidth / 1.3,
- child: ElevatedButton(
- onPressed: _registerUser,
- style: ElevatedButton.styleFrom(
- backgroundColor: Color(
- 0xFFA7887A), // Brownish color for Register
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(10),
- ),
- ),
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Text(
- "Register",
- style: TextStyle(
- fontSize: 16, color: Colors.white),
- ),
- SizedBox(width: 8),
- Icon(Icons.arrow_forward,
- color: Colors.white),
- ],
- ),
- ),
- ),
- SizedBox(height: 10),
- Text(
- "Already have an account?",
- style: TextStyle(
- fontSize: 16, color: Colors.grey[600]),
- ),
- SizedBox(height: 10),
- SizedBox(
- width: screenwidth / 1.3,
- child: ElevatedButton(
- onPressed: () {
- // Add your login logic here
- context.go('/login');
- },
- style: ElevatedButton.styleFrom(
- backgroundColor: Color(
- 0xFF82AFCB), // Blueish color for Login
- shape: RoundedRectangleBorder(
- 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),
- ],
- ),
- ),
- ),
- SizedBox(
- height: 10,
- ),
- Center(
- child: Container(
- height: screenheight / 8,
- width: screenwidth / 2,
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage(
- "assets/splash_screen/logo.png"), // Background image asset
- fit: BoxFit.fill,
- ),
- ),
- ))
- ],
- ),
- ),
- ),
- ),
- ),
- );
- }
-
- Widget registration_failed (BuildContext context) {
- double screenheight = MediaQuery.of(context).size.height;
- double screenwidth = MediaQuery.of(context).size.width;
- return Scaffold(
- body: Padding(
- padding: const EdgeInsets.all(20.0),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- SizedBox(height: screenheight / 8),
- buildIconContainer(Icons.report, Colors.red),
- SizedBox(height: 20),
- Text(
- "Sorry ${_usernameController.text}!",
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 16,
- fontWeight: FontWeight.w500,
- color: Color(0xFF414042)),
- ),
- SizedBox(height: 10),
- Text(
- "Your registration process failed. For further assistance, please contact support.",
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 14,
- color: Color(0xFF898C81),
- ),
- ),
- SizedBox(height: 10),
- ElevatedButton(
- onPressed: () => {
- setState(() {
- registrationFailed = false;
- registrationSuccess = false;
- _usernameController.clear();
- _emailController.clear();
- _passwordController.clear();
- _confirmpasswordController.clear();
- isChecked = false;
- })
- },
- child: Text(
- 'Retry',
- ),
- ),
- SizedBox(height: screenheight / 5),
- Center(
- child: Container(
- height: screenheight / 8,
- width: screenwidth / 2,
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage(
- "assets/splash_screen/logo.png"), // Background image asset
- fit: BoxFit.fill,
- ),
- ),
- ))
- ],
- ),
- ),
- );
- }
-
- Widget registration_success (BuildContext context) {
- double screenheight = MediaQuery.of(context).size.height;
- double screenwidth = MediaQuery.of(context).size.width;
- return Padding(
- padding: const EdgeInsets.all(20.0),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- SizedBox(height: screenheight / 8),
- buildIconContainer(Icons.report, Color(0xFF7DAFBC)),
- SizedBox(height: 20),
- Text(
- "Your registration is pending for Admin Approval.",
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 16,
- fontWeight: FontWeight.w500,
- color: Color(0xFF414042)),
- ),
- SizedBox(height: 10),
- Text(
- "Access will be granted once your account is approved.",
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 14,
- color: Color(0xFF898C81),
- ),
- ),
- SizedBox(height: 10),
- ElevatedButton(
- onPressed: () => {
- context.go('/login')
- // Navigator.pushReplacement(
- // context,
- // MaterialPageRoute(builder: (context) => LoginRoute()
- //
- // //ProfileScreen(userId: userID)
- // ),
- // ),
- },
- child: Text(
- 'Go to Login',
- ),
- ),
- SizedBox(height: screenheight / 5),
- Center(
- child: Container(
- height: screenheight / 8,
- width: screenwidth / 2,
- decoration: BoxDecoration(
- image: DecorationImage(
- image: AssetImage(
- "assets/splash_screen/logo.png"), // Background image asset
- fit: BoxFit.fill,
- ),
- ),
- ))
- ],
- ),
- );
- }
-
- Widget buildIconContainer(IconData icon, Color iconColor) {
- return Scaffold(
- body: Container(
+ Widget buildIconContainer(IconData icon, Color iconColor) {
+ return Container(
width: 60,
height: 60,
decoration: BoxDecoration(
@@ -667,8 +260,419 @@ class _RegisterScreenState extends State {
color: iconColor,
size: 30,
),
- ),
+ );
+ }
+
+ return Scaffold(
+ backgroundColor: Colors.white,
+ body: registrationSuccess
+ ? Padding(
+ padding: const EdgeInsets.all(20.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ SizedBox(height: screenheight / 8),
+ buildIconContainer(Icons.report, Color(0xFF7DAFBC)),
+ SizedBox(height: 20),
+ Text(
+ "Your registration is pending for Admin Approval.",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w500,
+ color: Color(0xFF414042)),
+ ),
+ SizedBox(height: 10),
+ Text(
+ "Access will be granted once your account is approved.",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 14,
+ color: Color(0xFF898C81),
+ ),
+ ),
+ SizedBox(height: 10),
+ ElevatedButton(
+ onPressed: () => {
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(builder: (context) => LoginRoute()
+
+ //ProfileScreen(userId: userID)
+ ),
+ ),
+ },
+ child: Text(
+ 'Go to Login',
+ ),
+ ),
+ SizedBox(height: screenheight / 5),
+ Center(
+ child: Container(
+ height: screenheight / 8,
+ width: screenwidth / 2,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ "assets/splash_screen/logo.png"), // Background image asset
+ fit: BoxFit.fill,
+ ),
+ ),
+ ))
+ ],
+ ),
+ )
+ : registrationFailed
+ ? Padding(
+ padding: const EdgeInsets.all(20.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ SizedBox(height: screenheight / 8),
+ buildIconContainer(Icons.report, Colors.red),
+ SizedBox(height: 20),
+ Text(
+ "Sorry ${_usernameController.text}!",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w500,
+ color: Color(0xFF414042)),
+ ),
+ SizedBox(height: 10),
+ Text(
+ "Your registration process failed. For further assistance, please contact support.",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 14,
+ color: Color(0xFF898C81),
+ ),
+ ),
+ SizedBox(height: 10),
+ ElevatedButton(
+ onPressed: () => {
+ setState(() {
+ registrationFailed = false;
+ registrationSuccess = false;
+ _usernameController.clear();
+ _emailController.clear();
+ _passwordController.clear();
+ _confirmpasswordController.clear();
+ isChecked = false;
+ })
+ },
+ child: Text(
+ 'Retry',
+ ),
+ ),
+ SizedBox(height: screenheight / 5),
+ Center(
+ child: Container(
+ height: screenheight / 8,
+ width: screenwidth / 2,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ "assets/splash_screen/logo.png"), // Background image asset
+ fit: BoxFit.fill,
+ ),
+ ),
+ ))
+ ],
+ ),
+ )
+ : Padding(
+ padding: const EdgeInsets.all(20.0),
+ child: Form(
+ key: _formKey,
+ child: SingleChildScrollView(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ SizedBox(height: screenheight / 6),
+ Text(
+ 'Register',
+ style: TextStyle(
+ fontSize: 32, fontWeight: FontWeight.w400),
+ ),
+ SizedBox(height: 10),
+ Text('Please enter your details'),
+
+ SizedBox(height: 20),
+ // Display this if registration is pending approval
+ TextFormField(
+ controller: _usernameController,
+ focusNode: _focusNodes[0],
+ decoration: InputDecoration(
+ hintText: _showHints[0] ? 'Username' : null,
+ prefixIcon: Icon(
+ Icons.person,
+ color: Colors.blue,
+ ),
+ border: OutlineInputBorder(),
+ counterText: '',
+ ),
+ validator: _validateUsername,
+ maxLength:
+ 40, // Set the maximum length to 20 characters
+ maxLengthEnforcement: MaxLengthEnforcement.enforced,
+ ),
+ SizedBox(height: 15),
+ TextFormField(
+ controller: _emailController,
+ focusNode: _focusNodes[1],
+ decoration: InputDecoration(
+ // hintText: 'Enter your email',
+ hintText:
+ _showHints[1] ? 'Enter your email' : null,
+ prefixIcon: Icon(
+ Icons.email,
+ color: Colors.blue,
+ ),
+ border: OutlineInputBorder(),
+ counterText: '',
+ ),
+ validator: _validateEmail,
+ maxLength: 320,
+ maxLengthEnforcement: MaxLengthEnforcement.enforced,
+ inputFormatters: [
+ LengthLimitingTextInputFormatter(
+ 320), // Limit to 320 characters
+ ],
+ ),
+ SizedBox(height: 15),
+ TextFormField(
+ controller: _passwordController,
+ focusNode: _focusNodes[2],
+ obscureText: _obscurePassword,
+ decoration: InputDecoration(
+ hintText:
+ _showHints[2] ? 'Enter your password' : null,
+ prefixIcon: Icon(
+ Icons.lock,
+ color: Colors.blue,
+ ),
+ suffixIcon: IconButton(
+ icon: Icon(
+ _obscurePassword
+ ? Icons.visibility
+ : Icons.visibility_off,
+ color: Colors.blue,
+ ),
+ onPressed: () {
+ setState(() {
+ _obscurePassword = !_obscurePassword;
+ });
+ },
+ ),
+ border: OutlineInputBorder(),
+ counterText: '',
+ ),
+ validator: _validatePassword,
+ maxLength: 40,
+ maxLengthEnforcement: MaxLengthEnforcement.enforced,
+ ),
+ SizedBox(height: 15),
+ TextFormField(
+ controller: _confirmpasswordController,
+ focusNode: _focusNodes[3],
+ obscureText: _obscureConfirmPassword,
+ decoration: InputDecoration(
+ hintText:
+ _showHints[3] ? 'Confirm password' : null,
+ prefixIcon: Icon(
+ Icons.lock,
+ color: Colors.blue,
+ ),
+ suffixIcon: IconButton(
+ icon: Icon(
+ _obscureConfirmPassword
+ ? Icons.visibility
+ : Icons.visibility_off,
+ color: Colors.blue,
+ ),
+ onPressed: () {
+ setState(() {
+ _obscureConfirmPassword =
+ !_obscureConfirmPassword;
+ });
+ },
+ ),
+ border: OutlineInputBorder(),
+ counterText: '',
+ ),
+ validator: _validateConfirmPassword,
+ maxLength: 40,
+ maxLengthEnforcement: MaxLengthEnforcement.enforced,
+ inputFormatters: [
+ LengthLimitingTextInputFormatter(
+ 64), // Limit to 40 characters
+ ],
+ ),
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Checkbox(
+ value: isChecked,
+ onChanged: (value) {
+ setState(() {
+ isChecked = value ?? false;
+ showError = false;
+ });
+ },
+ side: BorderSide(
+ color: showError ? Colors.red : Colors.grey,
+ width: 1.5,
+ ),
+ ),
+ Expanded(
+ child: Text.rich(
+ TextSpan(
+ text: 'I agree to ',
+ children: [
+ TextSpan(
+ text: 'Terms & Conditions',
+ style: TextStyle(color: Colors.blue),
+ ),
+ TextSpan(text: ' and '),
+ TextSpan(
+ text: 'Privacy Policy',
+ style: TextStyle(color: Colors.blue),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ if (showError)
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(left: 10.0),
+ child: Text(
+ 'Please agree to terms and conditions.',
+ style: TextStyle(
+ color: Colors.red[700],
+ fontSize: 12,
+ ),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 20),
+ SizedBox(
+ width: screenwidth / 1.3,
+ child: ElevatedButton(
+ onPressed: _registerUser,
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Color(
+ 0xFFA7887A), // Brownish color for Register
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ ),
+ ),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(
+ "Register",
+ style: TextStyle(
+ fontSize: 16, color: Colors.white),
+ ),
+ SizedBox(width: 8),
+ Icon(Icons.arrow_forward,
+ color: Colors.white),
+ ],
+ ),
+ ),
+ ),
+ SizedBox(height: 10),
+ Text(
+ "Already have an account?",
+ style: TextStyle(
+ fontSize: 16, color: Colors.grey[600]),
+ ),
+ SizedBox(height: 10),
+ SizedBox(
+ width: screenwidth / 1.3,
+ child: ElevatedButton(
+ onPressed: () {
+ // Add your login logic here
+ },
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Color(
+ 0xFF82AFCB), // Blueish color for Login
+ shape: RoundedRectangleBorder(
+ 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
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => LoginRoute()),
+ // MaterialPageRoute(builder: (context) => LoginRoute(userId: userID)),
+ );
+ },
+ 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(
+ height: 10,
+ ),
+ Center(
+ child: Container(
+ height: screenheight / 8,
+ width: screenwidth / 2,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ "assets/splash_screen/logo.png"), // Background image asset
+ fit: BoxFit.fill,
+ ),
+ ),
+ ))
+ ],
+ ),
+ ),
+ ),
+ ),
);
}
}
-
diff --git a/lib/presentation/Screens/profilepage.dart b/lib/presentation/Screens/profilepage.dart
index fd2b0e34..c155b517 100644
--- a/lib/presentation/Screens/profilepage.dart
+++ b/lib/presentation/Screens/profilepage.dart
@@ -597,12 +597,10 @@ class _ProfileScreenState extends State {
Center(
child: GestureDetector(
onTap: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) =>
- Changepassword(userId: widget.userId)),
- );
+ final userId = widget.userId;
+ final email = _emailController.text;
+
+ context.go('/createNewPw/$userId/$email');
},
child: Text(
"Change Password",
diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart
index 989e799d..cbf28f0a 100644
--- a/lib/presentation/routes/auth_routes/login_route.dart
+++ b/lib/presentation/routes/auth_routes/login_route.dart
@@ -740,5 +740,206 @@ class _LoginRouteState extends State {
),
),
);
+<<<<<<< HEAD
+=======
+ final form = Form(
+ key: formKey,
+ child: Column(
+ children: [
+ ThemedFormField(
+ hintText: context.translate(
+ 'Email',
+ 'بريد إلكتروني',
+ ),
+ validator: FieldValidator.email(),
+ imgPath: MiscIconAssetPath.person,
+ controller: emailCtl,
+ ),
+ 15.verticalSpace,
+ ThemedFormField(
+ validator: (text) {
+ if (text!.length < 8) {
+ return 'The password must be at least 8 characters';
+ }
+ return FieldValidator.password(minLength: 8)(text);
+ },
+ hintText: context.translate(
+ 'Password',
+ 'كلمة المرور',
+ ),
+ imgPath: MiscIconAssetPath.lock,
+ controller: pwCtl,
+ isObscurable: true,
+ ),
+ // 6.verticalSpace,
+ Align(
+ alignment: AlignmentDirectional.topEnd,
+ child: forgotPwBtn,
+ ),
+ 10.verticalSpace,
+ loginBtn,
+ ],
+ ),
+ );
+ final helloAndPleaseLoginTexts = Column(
+ children: [
+ Text(
+ context.translate(
+ 'Hello Again!',
+ 'مرحبا مجددا!',
+ ),
+ style: TextStyle(
+ fontFamily: context.translate(
+ 'Roboto',
+ 'NotoKufi',
+ ),
+ fontSize: 40,
+ fontWeight: FontWeight.w300,
+ ),
+ ),
+ 10.verticalSpace,
+ Text(
+ context.translate(
+ 'Please login to access UAE’s key official statistics',
+ 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة',
+ ),
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontFamily: context.translate(
+ 'Roboto',
+ 'NotoKufi',
+ ),
+ fontSize: 18,
+ color: const Color(0xff898C81),
+ fontWeight: FontWeight.w700,
+ ),
+ ),
+ ],
+ );
+ final dontHaveAnAccountRegisterBtn = TextButton(
+ onPressed: () => {
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => RegisterScreen()),
+ ),
+ },
+ child: Text.rich(
+ textAlign: TextAlign.center,
+ TextSpan(
+ style: TextStyle(
+ fontFamily: context.translate(
+ 'Roboto',
+ 'NotoKufi',
+ ),
+ fontSize: 18,
+ fontWeight: FontWeight.bold,
+ ),
+ children: [
+ TextSpan(
+ text: context.translate(
+ 'Don\'t have an account? ',
+ 'ليس لديك حساب؟',
+ ),
+ style: const TextStyle(
+ color: Color(0xff898C81),
+ ),
+ ),
+ const TextSpan(
+ text: ' ',
+ ),
+ TextSpan(
+ text: context.translate(
+ 'Register Now',
+ 'سجل الان',
+ ),
+ style: TextStyle(
+ color: MyTheme.topicColor(IndicatorTopic.economy).shade600,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ final continueAsGuestBtn = SizedBox(
+ width: double.infinity,
+ child: ElevatedButton(
+ onPressed: () => context
+ .go('/${context.language}/${BottomNavBarItem.home.routePath}'),
+ style: ButtonStyle(
+ shape: WidgetStatePropertyAll(
+ RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ ),
+ ),
+ padding: const WidgetStatePropertyAll(
+ EdgeInsets.symmetric(vertical: 10.5),
+ ),
+ textStyle: WidgetStatePropertyAll(
+ TextStyle(
+ fontFamily: context.translate(
+ 'Roboto',
+ 'NotoKufi',
+ ),
+ fontSize: 16,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ backgroundColor: WidgetStatePropertyAll(
+ MyTheme.topicColor(IndicatorTopic.environment),
+ ),
+ foregroundColor: const WidgetStatePropertyAll(
+ Colors.white,
+ ),
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ context.translate(
+ 'Continue as Guest',
+ 'استمر كضيف',
+ ),
+ ),
+ 6.horizontalSpace,
+ const Icon(Icons.chevron_right_outlined),
+ ],
+ ),
+ ),
+ );
+ final fcscBanner = Image.asset(
+ BannerAssetPath.fcsc,
+ height: 56,
+ );
+ final screenWidth = MediaQuery.of(context).size.width;
+ final listViewHorizontalPadding =
+ screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2;
+ final scaffoldBody = ListView(
+ padding: EdgeInsets.symmetric(
+ horizontal: listViewHorizontalPadding.toDouble(),
+ ),
+ children: [
+ 36.verticalSpace,
+ const Align(
+ alignment: AlignmentDirectional.topEnd,
+ child: LangToggle(),
+ ),
+ 16.verticalSpace,
+ helloAndPleaseLoginTexts,
+ 42.verticalSpace,
+ form,
+ 20.verticalSpace,
+ dontHaveAnAccountRegisterBtn,
+ 36.verticalSpace,
+ continueAsGuestBtn,
+ 72.verticalSpace,
+ fcscBanner,
+ ],
+ );
+ final bgScaffold = Scaffold(
+ backgroundColor: Colors.white,
+ body: SafeArea(child: scaffoldBody),
+ );
+ return bgScaffold;
+>>>>>>> b0c5ebce3deb7da2aa24b0ea5ffe684df7dfb7bf
}
}
diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart
index 3d74ef02..080be24f 100644
--- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart
+++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart
@@ -135,7 +135,6 @@ class _EditProfileState extends State {
Future checkUserId() async {
userId = await getUserId();
- //userId = 'tplu4by67phkfoq';
if (userId != null && userId.isNotEmpty) {
print('User ID: $userId');
_fetchUserData();
@@ -189,25 +188,6 @@ class _EditProfileState extends State {
} else {
_avatarUrl = ''; // Reset to default or empty
}
-
- // String avatarFilename = userDetailsResponse.data['avatar'] ?? '';
- // //print("PROFILE AVAILABLE -$avatarFilename");
- // String recordId = userId;
- // //String recordId = userDetailsResponse.data['id'] ?? "";
- // print("PROFILE AVAILABLE -${userDetailsResponse.data['id']}");
- // //print("User ID: $recordId");
-
- //String collectionId = userDetailsResponse.data['collectionId'] ?? '_pb_users_auth_';
-
- // Ensure recordId and avatarFilename are valid
- // if (avatarFilename.isNotEmpty && recordId.isNotEmpty) {
- // print("PROFILE AVAILABLE");
- // String _avatarUrl = 'https://pb.venbait.in/api/files/$collectionId/$recordId/$avatarFilename';
- // print("PROFILE AVAILABLE1- $_avatarUrl");
- // //_avatarUrl = File(imageUrl); // This won't work directly for a URL, you need to download the image first
- // } else {
- // print("PROFILE NOT AVAILABLE");
- // }
});
} catch (e) {
print('Error fetching user details: $e');
@@ -672,12 +652,8 @@ class _EditProfileState extends State {
Center(
child: GestureDetector(
onTap: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) =>
- Changepassword(userId: userId)),
- );
+ final email = _emailController.text;
+ context.go('/createNewPw/$userId/$email');
},
child: Text(
"Change Password",
@@ -691,16 +667,6 @@ class _EditProfileState extends State {
ElevatedButton.icon(
onPressed: () {
showConfirmationDialog(context);
-
- // if (_formKey.currentState?.validate() ?? false){
- // _formKey.currentState?.save();
- // showConfirmationDialog(context);
- // } else {
- // setState(() {
- // showError =
- // !isChecked; // Show error if the checkbox is not checked
- // });
- // }
},
icon: Icon(
Icons.save,
diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart
index 7d87d47a..79c919c0 100644
--- a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart
+++ b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart
@@ -92,9 +92,11 @@ class _ManageUserRouterState extends State {
filteredUserData.sort((a, b) {
final aValue = getField(a);
final bValue = getField(b);
- if (aValue == null || bValue == null) {
- return 0; // Handle null-safe sorting if needed
- }
+ // Handle null values
+ if (aValue == null && bValue == null) return 0;
+ if (aValue == null) return ascending ? -1 : 1;
+ if (bValue == null) return ascending ? 1 : -1;
+ // Compare values
return ascending
? Comparable.compare(aValue, bValue)
: Comparable.compare(bValue, aValue);
@@ -248,20 +250,24 @@ class _ManageUserRouterState extends State {
columns: [
DataColumn(
label: const Text('User Name'),
- onSort: (columnIndex, ascending) => _sort(
- (user) => user.userName, columnIndex, ascending),
+ onSort: (columnIndex, ascending) {
+ _sort((user) => user.userName.toLowerCase(),
+ columnIndex, ascending);
+ },
),
DataColumn(
label: const Text('Email ID'),
- onSort: (columnIndex, ascending) => _sort(
- (user) => user.emailId, columnIndex, ascending),
+ onSort: (columnIndex, ascending) {
+ _sort((user) => user.emailId.toLowerCase(),
+ columnIndex, ascending);
+ },
),
DataColumn(
label: const Text('Registration Date'),
onSort: (columnIndex, ascending) {
_sort(
- (user) => DateTime.tryParse(
- user.registrationDate), // Convert to DateTime
+ (user) => DateFormat('dd/MM/yyyy')
+ .parse(user.registrationDate),
columnIndex,
ascending,
);
@@ -269,8 +275,10 @@ class _ManageUserRouterState extends State {
),
DataColumn(
label: const Text('Status'),
- onSort: (columnIndex, ascending) => _sort(
- (user) => user.status, columnIndex, ascending),
+ onSort: (columnIndex, ascending) {
+ _sort((user) => user.status.toLowerCase(),
+ columnIndex, ascending);
+ },
),
],
rows: filteredUserData.isEmpty