change password functionality added
This commit is contained in:
parent
d6c475cf3a
commit
c34e25d5e1
@ -56,7 +56,7 @@ class AuthUseCase extends _$AuthUseCase {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> login(String email, String pw) async {
|
||||
Future<SessionEntity> login(String email, String pw) async {
|
||||
final session = await _repo.login(email, pw);
|
||||
final localPrefs = await getIt.call<TLocalPreferencesRepo>().get();
|
||||
if (localPrefs != null) {
|
||||
@ -66,6 +66,7 @@ class AuthUseCase extends _$AuthUseCase {
|
||||
);
|
||||
}
|
||||
state = AsyncData(session);
|
||||
return session; // Return the session with user details.
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'dart:convert';
|
||||
import 'otp_verification.dart';
|
||||
|
||||
class Changepassword extends StatefulWidget {
|
||||
const Changepassword({Key? key}) : super(key: key);
|
||||
// final String email;
|
||||
final String userId;
|
||||
const Changepassword({Key? key, required this.userId});
|
||||
|
||||
@override
|
||||
State<Changepassword> createState() => _ResetPasswordScreenState();
|
||||
@ -53,7 +57,7 @@ class _ResetPasswordScreenState extends State<Changepassword> {
|
||||
//print('userDetails ->: $userData');
|
||||
if (userData['items'].isNotEmpty) {
|
||||
// Email exists; retrieve user ID
|
||||
final userId = userData['items'][0]['id'];
|
||||
//final userId = userData['items'][0]['id'];
|
||||
|
||||
// Proceed with OTP request
|
||||
final otpResponse = await http.post(
|
||||
@ -87,7 +91,7 @@ class _ResetPasswordScreenState extends State<Changepassword> {
|
||||
MaterialPageRoute(
|
||||
builder: (context) => EmailVerificationScreen(
|
||||
email: email,
|
||||
userId: userId, // Pass user ID to the next screen
|
||||
userId: widget.userId, // Pass user ID to the next screen
|
||||
otp: otp,
|
||||
otpId: otpId,
|
||||
sendVerificationCode: sendVerificationCode,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:uae_stat/presentation/Screens/profilepage.dart';
|
||||
|
||||
@ -12,7 +13,7 @@ class ConfirmPassword extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ConfirmPasswordState extends State<ConfirmPassword> {
|
||||
final _pb = PocketBase('https://pb.venbait.in');
|
||||
final pb = PocketBase('https://pb.venbait.in');
|
||||
// final pb = PocketBase('http://127.0.0.1:8090');
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
bool _obscurePassword = true;
|
||||
@ -44,8 +45,7 @@ class _ConfirmPasswordState extends State<ConfirmPassword> {
|
||||
//print('userRecord- $userId');
|
||||
|
||||
// Authenticate as admin
|
||||
|
||||
final adminAuth = await _pb.admins
|
||||
final adminAuth = await pb.admins
|
||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||
final token = adminAuth.token;
|
||||
|
||||
@ -53,10 +53,9 @@ class _ConfirmPasswordState extends State<ConfirmPassword> {
|
||||
'Authorization': 'Bearer $token',
|
||||
};
|
||||
|
||||
final userRecord = await _pb.collection('users').getOne(userId);
|
||||
final userRecord = await pb.collection('users').getOne(userId);
|
||||
//print('userRecord- $userRecord');
|
||||
final oldPassword = userRecord.data['password'];
|
||||
print(oldPassword);
|
||||
|
||||
// Check if the new password is the same as the old password
|
||||
if (oldPassword == newPassword) {
|
||||
@ -71,10 +70,14 @@ class _ConfirmPasswordState extends State<ConfirmPassword> {
|
||||
}
|
||||
|
||||
// Update password
|
||||
await _pb.collection('users').update(
|
||||
userId, // User ID
|
||||
body: {'password': newPassword}, // Updated password
|
||||
);
|
||||
await pb.collection('users').update(
|
||||
userId, // User ID
|
||||
body: {
|
||||
'password': newPassword,
|
||||
'passwordConfirm': newPassword,
|
||||
}, // Updated password
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
// Show success Snackbar
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
|
||||
29
lib/presentation/Screens/demo_home.dart
Normal file
29
lib/presentation/Screens/demo_home.dart
Normal file
@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
|
||||
import '../components/my_drawer.dart';
|
||||
|
||||
class DemoHome extends StatefulWidget {
|
||||
@override
|
||||
State<DemoHome> createState() => _DemoHomeState();
|
||||
}
|
||||
|
||||
class _DemoHomeState extends State<DemoHome> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
drawer: const MyDrawer(),
|
||||
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'),
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
|
||||
import 'confirm_password.dart';
|
||||
|
||||
class EmailVerificationScreen extends StatefulWidget {
|
||||
@ -23,8 +22,8 @@ class EmailVerificationScreen extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _EmailVerificationScreenState extends State<EmailVerificationScreen> {
|
||||
final pb = PocketBase('https://pb.venbait.in');
|
||||
// final pb = PocketBase('http://127.0.0.1:8090');
|
||||
final _pb = PocketBase('https://pb.venbait.in');
|
||||
final List<TextEditingController> _otpControllers =
|
||||
List.generate(4, (_) => TextEditingController());
|
||||
int _secondsRemaining = 120; // 2 minutes timer
|
||||
@ -131,7 +130,7 @@ class _EmailVerificationScreenState extends State<EmailVerificationScreen> {
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
"Please Enter the 4 digit Code Sent to\nrjosh289778@gmail.com",
|
||||
"Please Enter the 4 digit Code Sent to ${widget.email}",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
@ -181,7 +180,7 @@ class _EmailVerificationScreenState extends State<EmailVerificationScreen> {
|
||||
SizedBox(height: 16),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
text: "Code Expires in ",
|
||||
text: "Code Expires in ",
|
||||
style: TextStyle(color: Colors.grey[600]),
|
||||
children: [
|
||||
TextSpan(
|
||||
@ -207,7 +206,8 @@ class _EmailVerificationScreenState extends State<EmailVerificationScreen> {
|
||||
child: Text(
|
||||
"Resend Code",
|
||||
style: TextStyle(
|
||||
color: Colors.brown, fontWeight: FontWeight.bold),
|
||||
color: _canResend ? Colors.brown : Colors.grey,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
@ -4,12 +4,17 @@ import 'dart:io';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
||||
|
||||
import '../components/my_bottom_nav_bar.dart';
|
||||
import 'changepassword.dart';
|
||||
import 'demo_home.dart';
|
||||
|
||||
class ProfileScreen extends StatefulWidget {
|
||||
final String userId; // Add this field to hold the user ID
|
||||
@ -67,6 +72,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
final adminAuth = await _pb.admins
|
||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||
final adminToken = adminAuth.token;
|
||||
print('adminToken- ${adminToken}');
|
||||
final userDetailsResponse = await _pb.collection('users').getOne(
|
||||
widget.userId,
|
||||
headers: {
|
||||
@ -200,6 +206,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
_resetFormFields();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text("Profile updated successfully!")));
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => DemoHome()),
|
||||
);
|
||||
} catch (error) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text("Failed to update profile: $error")));
|
||||
@ -518,7 +528,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => Changepassword()),
|
||||
builder: (context) =>
|
||||
Changepassword(userId: widget.userId)),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@ -6,6 +7,7 @@ import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/presentation/Screens/profilepage.dart';
|
||||
|
||||
import '../../infrastructure/services/pocketbase_service.dart';
|
||||
import '../routes/auth_routes/login_route.dart';
|
||||
|
||||
class RegisterScreen extends StatefulWidget {
|
||||
@override
|
||||
@ -17,6 +19,8 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
final _usernameController = TextEditingController();
|
||||
final _emailController = TextEditingController();
|
||||
final _passwordController = TextEditingController();
|
||||
final _confirmpasswordController = TextEditingController();
|
||||
|
||||
bool _obscurePassword = true;
|
||||
bool _obscureConfirmPassword = true;
|
||||
bool isChecked = false;
|
||||
@ -25,56 +29,153 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
bool registrationSuccess = false;
|
||||
bool registrationFailed = false;
|
||||
dynamic userID;
|
||||
|
||||
final pb = PocketBase('https://pb.venbait.in');
|
||||
// final pb = PocketBase('http://127.0.0.1:8090');
|
||||
|
||||
// Add focus nodes and hint states
|
||||
final List<FocusNode> _focusNodes = List.generate(4, (_) => FocusNode());
|
||||
final List<bool> _showHints = [
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]; // One for each TextField
|
||||
|
||||
String _getControllerText(int index) {
|
||||
if (index == 0) return _usernameController.text;
|
||||
if (index == 1) return _emailController.text;
|
||||
if (index == 2) return _passwordController.text;
|
||||
if (index == 3) return _confirmpasswordController.text;
|
||||
return '';
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
// Add listeners for focus nodes
|
||||
for (int i = 0; i < _focusNodes.length; i++) {
|
||||
_focusNodes[i].addListener(() {
|
||||
setState(() {
|
||||
// Hide hint when focused and text is not empty
|
||||
_showHints[i] =
|
||||
!_focusNodes[i].hasFocus && (_getControllerText(i).isEmpty);
|
||||
});
|
||||
});
|
||||
|
||||
// Listen to text changes
|
||||
if (i == 0) {
|
||||
_usernameController.addListener(() {
|
||||
setState(() {
|
||||
_showHints[i] =
|
||||
!_focusNodes[i].hasFocus && (_getControllerText(i).isEmpty);
|
||||
});
|
||||
});
|
||||
} else if (i == 1) {
|
||||
_emailController.addListener(() {
|
||||
setState(() {
|
||||
_showHints[i] =
|
||||
!_focusNodes[i].hasFocus && (_getControllerText(i).isEmpty);
|
||||
});
|
||||
});
|
||||
} else if (i == 2) {
|
||||
_passwordController.addListener(() {
|
||||
setState(() {
|
||||
_showHints[i] =
|
||||
!_focusNodes[i].hasFocus && (_getControllerText(i).isEmpty);
|
||||
});
|
||||
});
|
||||
} else if (i == 3) {
|
||||
_confirmpasswordController.addListener(() {
|
||||
setState(() {
|
||||
_showHints[i] =
|
||||
!_focusNodes[i].hasFocus && (_getControllerText(i).isEmpty);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
for (var focusNode in _focusNodes) {
|
||||
focusNode.dispose();
|
||||
}
|
||||
_usernameController.dispose();
|
||||
_emailController.dispose();
|
||||
_passwordController.dispose();
|
||||
_confirmpasswordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
String? _validateUsername(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Required';
|
||||
} else if (RegExp(r'[^a-zA-Z0-9]').hasMatch(value)) {
|
||||
} else if (value.length > 40) {
|
||||
return 'Must not exceed 40 characters';
|
||||
} else if (!RegExp(r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF]+$")
|
||||
.hasMatch(value)) {
|
||||
return 'Invalid Characters';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//else if (RegExp(r'[^a-zA-Z0-9]').hasMatch(value))
|
||||
|
||||
String? _validateEmail(String? value) {
|
||||
// Regex to allow special characters, accented characters, and alphanumeric characters
|
||||
final emailRegex =
|
||||
r'^[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+@[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+\.[a-zA-Z]{2,}$';
|
||||
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Required';
|
||||
} else if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value)) {
|
||||
} else if (!RegExp(emailRegex).hasMatch(value)) {
|
||||
return 'Invalid Email';
|
||||
}
|
||||
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 < 6) {
|
||||
return 'Password must be at least 6 characters';
|
||||
} 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? _validateConfirmPassword(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 || value.length > 40) {
|
||||
return 'Password must be at least 8characters';
|
||||
} else if (!regex.hasMatch(value)) {
|
||||
return 'Password contains invalid characters';
|
||||
} else if (value != _password) {
|
||||
return 'Passwords do not match';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -84,14 +185,16 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
try {
|
||||
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, // PocketBase requires password confirmation
|
||||
'passwordConfirm': _passwordController.text,
|
||||
// 'verified': true,
|
||||
}, headers: {
|
||||
'Authorization': adminToken
|
||||
});
|
||||
@ -194,9 +297,10 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
onPressed: () => {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
ProfileScreen(userId: userID)),
|
||||
MaterialPageRoute(builder: (context) => LoginRoute()
|
||||
|
||||
//ProfileScreen(userId: userID)
|
||||
),
|
||||
),
|
||||
},
|
||||
child: Text(
|
||||
@ -247,9 +351,17 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
ElevatedButton(
|
||||
onPressed: () => context.go(
|
||||
'/${context.language}/login',
|
||||
),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
registrationFailed = false;
|
||||
registrationSuccess = false;
|
||||
_usernameController.clear();
|
||||
_emailController.clear();
|
||||
_passwordController.clear();
|
||||
_confirmpasswordController.clear();
|
||||
isChecked = false;
|
||||
})
|
||||
},
|
||||
child: Text(
|
||||
'Retry',
|
||||
),
|
||||
@ -286,12 +398,14 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
),
|
||||
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: 'Username',
|
||||
hintText: _showHints[0] ? 'Username' : null,
|
||||
prefixIcon: Icon(
|
||||
Icons.person,
|
||||
color: Colors.blue,
|
||||
@ -307,22 +421,34 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
SizedBox(height: 15),
|
||||
TextFormField(
|
||||
controller: _emailController,
|
||||
focusNode: _focusNodes[1],
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Enter your email',
|
||||
// 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: 'Enter your password',
|
||||
hintText:
|
||||
_showHints[2] ? 'Enter your password' : null,
|
||||
prefixIcon: Icon(
|
||||
Icons.lock,
|
||||
color: Colors.blue,
|
||||
@ -341,14 +467,20 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
},
|
||||
),
|
||||
border: OutlineInputBorder(),
|
||||
counterText: '',
|
||||
),
|
||||
validator: _validatePassword,
|
||||
maxLength: 40,
|
||||
maxLengthEnforcement: MaxLengthEnforcement.enforced,
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
TextFormField(
|
||||
controller: _confirmpasswordController,
|
||||
focusNode: _focusNodes[3],
|
||||
obscureText: _obscureConfirmPassword,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Confirm password',
|
||||
hintText:
|
||||
_showHints[3] ? 'Confirm password' : null,
|
||||
prefixIcon: Icon(
|
||||
Icons.lock,
|
||||
color: Colors.blue,
|
||||
@ -368,8 +500,15 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
},
|
||||
),
|
||||
border: OutlineInputBorder(),
|
||||
counterText: '',
|
||||
),
|
||||
validator: _validateConfirmPassword,
|
||||
maxLength: 40,
|
||||
maxLengthEnforcement: MaxLengthEnforcement.enforced,
|
||||
inputFormatters: [
|
||||
LengthLimitingTextInputFormatter(
|
||||
64), // Limit to 40 characters
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
@ -414,7 +553,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 10.0),
|
||||
child: Text(
|
||||
'Required',
|
||||
'Please agree to terms and conditions.',
|
||||
style: TextStyle(
|
||||
color: Colors.red[700],
|
||||
fontSize: 12,
|
||||
@ -470,18 +609,48 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
||||
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: 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),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -9,18 +9,57 @@ import 'package:uae_stat/domain/use_cases/auth_use_case.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
|
||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
|
||||
import 'package:uae_stat/presentation/Screens/demo_home.dart';
|
||||
import 'package:uae_stat/presentation/components/dialogs.dart';
|
||||
import 'package:uae_stat/presentation/components/lang_toggle.dart';
|
||||
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
|
||||
import 'package:uae_stat/presentation/components/space.dart';
|
||||
import 'package:uae_stat/presentation/components/themed_text_field.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/profile/profile_route.dart';
|
||||
import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
||||
|
||||
import '../../Screens/profilepage.dart';
|
||||
import '../../Screens/registration.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
|
||||
class LoginRoute extends HookConsumerWidget {
|
||||
const LoginRoute({super.key});
|
||||
final pb = PocketBase('https://pb.venbait.in');
|
||||
// final _pb = PocketBase('http://127.0.0.1:8090');
|
||||
LoginRoute({super.key});
|
||||
|
||||
static final formKey = GlobalKey<FormState>();
|
||||
|
||||
Future<bool> profileStatus(String userId) async {
|
||||
try {
|
||||
// Authenticate admin
|
||||
final adminAuth = await pb.admins.authWithPassword(
|
||||
'pb@venbainfotech.com',
|
||||
'pb@venbainfotech.com',
|
||||
);
|
||||
final String adminToken = adminAuth.token;
|
||||
print('adminToken: $adminToken');
|
||||
|
||||
// Fetch user details
|
||||
final userDetailsResponse = await pb.collection('users').getOne(
|
||||
userId,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $adminToken',
|
||||
},
|
||||
);
|
||||
print('userDetailsLogin: $userDetailsResponse');
|
||||
|
||||
// Check if 'is_profile_completed' is true or false
|
||||
if (userDetailsResponse != null &&
|
||||
userDetailsResponse.data['is_profile_completed'] != null) {
|
||||
return userDetailsResponse.data['is_profile_completed'];
|
||||
} else {
|
||||
return false; // Default to false if the field is missing or response is null
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching user details: $e');
|
||||
return false; // Return false on error
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final emailCtl = useTextEditingController();
|
||||
@ -119,76 +158,95 @@ class LoginRoute extends HookConsumerWidget {
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
// final isValid = formKey.currentState!.validate();
|
||||
// if (!isValid) return;
|
||||
// await context.loaderWithErrorDialog(
|
||||
// () => ref
|
||||
// .read(
|
||||
// authUseCaseProvider.notifier,
|
||||
// )
|
||||
// .login(
|
||||
// emailCtl.text,
|
||||
// pwCtl.text,
|
||||
// ),
|
||||
// errorDialogBuilder: (
|
||||
// error, [
|
||||
// StackTrace? stackTrace,
|
||||
// ]) {
|
||||
// if (error == LoginError.invalidEmailPw) {
|
||||
// return context.simpleDialog(
|
||||
// title: context.translate(
|
||||
// 'Incorrect credentials',
|
||||
// 'أوراق غير صحيحة',
|
||||
// ),
|
||||
// content: context.translate(
|
||||
// 'Your email or password is invalid. Please try again.',
|
||||
// 'بريدك الإلكتروني أو كلمة المرور غير صالحة. حاول مرة اخرى.',
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// if (error == LoginError.emailAddressNotVerified) {
|
||||
// return context.simpleDialog(
|
||||
// title: context.translate(
|
||||
// 'Verification Error',
|
||||
// 'خطأ التحقق',
|
||||
// ),
|
||||
// content: context.translate(
|
||||
// '${emailCtl.text} is not a verified email address. Please check your email for a verification link.',
|
||||
// '${emailCtl.text} ليس عنوان بريد إلكتروني تم التحقق منه. يرجى التحقق من بريدك الإلكتروني للحصول على رابط التحقق.',
|
||||
// ),
|
||||
// extraAction: ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// Navigator.of(
|
||||
// context,
|
||||
// rootNavigator: true,
|
||||
// ).pop();
|
||||
// await context.loaderWithErrorDialog(
|
||||
// () => ref
|
||||
// .read(authUseCaseProvider.notifier)
|
||||
// .requestVerificationEmail(emailCtl.text),
|
||||
// );
|
||||
// if (!context.mounted) return;
|
||||
// context.simpleDialog(
|
||||
// title: 'Email Re-sent',
|
||||
// content:
|
||||
// 'We\'ve sent you the verification email at ${emailCtl.text} again.',
|
||||
// );
|
||||
// },
|
||||
// child: Text(
|
||||
// context.translate(
|
||||
// 'I did not receive an email',
|
||||
// 'لم أتلق بريدًا إلكترونيًا',
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// return context.simpleDialog();
|
||||
// },
|
||||
// );
|
||||
// if (!context.mounted) return;
|
||||
final isValid = formKey.currentState!.validate();
|
||||
if (!isValid) return;
|
||||
final session = await context.loaderWithErrorDialog(
|
||||
() => ref
|
||||
.read(
|
||||
authUseCaseProvider.notifier,
|
||||
)
|
||||
.login(
|
||||
emailCtl.text,
|
||||
pwCtl.text,
|
||||
),
|
||||
errorDialogBuilder: (
|
||||
error, [
|
||||
StackTrace? stackTrace,
|
||||
]) {
|
||||
if (error == LoginError.invalidEmailPw) {
|
||||
return context.simpleDialog(
|
||||
title: context.translate(
|
||||
'Incorrect credentials',
|
||||
'أوراق غير صحيحة',
|
||||
),
|
||||
content: context.translate(
|
||||
'Your email or password is invalid. Please try again.',
|
||||
'بريدك الإلكتروني أو كلمة المرور غير صالحة. حاول مرة اخرى.',
|
||||
),
|
||||
);
|
||||
}
|
||||
if (error == LoginError.emailAddressNotVerified) {
|
||||
return context.simpleDialog(
|
||||
title: context.translate(
|
||||
'Verification Error',
|
||||
'خطأ التحقق',
|
||||
),
|
||||
content: context.translate(
|
||||
'${emailCtl.text} is not a verified email address. Please check your email for a verification link.',
|
||||
'${emailCtl.text} ليس عنوان بريد إلكتروني تم التحقق منه. يرجى التحقق من بريدك الإلكتروني للحصول على رابط التحقق.',
|
||||
),
|
||||
extraAction: ElevatedButton(
|
||||
onPressed: () async {
|
||||
Navigator.of(
|
||||
context,
|
||||
rootNavigator: true,
|
||||
).pop();
|
||||
await context.loaderWithErrorDialog(
|
||||
() => ref
|
||||
.read(authUseCaseProvider.notifier)
|
||||
.requestVerificationEmail(emailCtl.text),
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
context.simpleDialog(
|
||||
title: 'Email Re-sent',
|
||||
content:
|
||||
'We\'ve sent you the verification email at ${emailCtl.text} again.',
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
context.translate(
|
||||
'I did not receive an email',
|
||||
'لم أتلق بريدًا إلكترونيًا',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return context.simpleDialog();
|
||||
},
|
||||
);
|
||||
if (!context.mounted || session == null) return;
|
||||
// Extract userId from the session
|
||||
final userId = session.id;
|
||||
|
||||
final bool isUpdate = await profileStatus(userId);
|
||||
|
||||
print('Is profile completed: $isUpdate');
|
||||
|
||||
if (isUpdate) {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => DemoHome()),
|
||||
);
|
||||
} else {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ProfileScreen(userId: userId)),
|
||||
);
|
||||
}
|
||||
|
||||
// context.go('/${context.language}/${BottomNavBarItem.home.routePath}');
|
||||
context.go('/Profile');
|
||||
},
|
||||
style: ButtonStyle(
|
||||
shape: WidgetStatePropertyAll(
|
||||
@ -224,7 +282,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
children: [
|
||||
Text(
|
||||
context.translate(
|
||||
'Login log',
|
||||
'Login',
|
||||
'تسجيل الدخول',
|
||||
),
|
||||
),
|
||||
@ -309,7 +367,12 @@ class LoginRoute extends HookConsumerWidget {
|
||||
],
|
||||
);
|
||||
final dontHaveAnAccountRegisterBtn = TextButton(
|
||||
onPressed: () => context.go('/${context.language}/register'),
|
||||
onPressed: () => {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => RegisterScreen()),
|
||||
),
|
||||
},
|
||||
child: Text.rich(
|
||||
textAlign: TextAlign.center,
|
||||
TextSpan(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user