login and register UI changes added
This commit is contained in:
parent
b13aa81ad9
commit
5b922b4355
@ -15,12 +15,12 @@ if (localPropertiesFile.exists()) {
|
|||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = "7"
|
flutterVersionCode = "9"
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||||
if (flutterVersionName == null) {
|
if (flutterVersionName == null) {
|
||||||
flutterVersionName = "1.0.6"
|
flutterVersionName = "1.0.8"
|
||||||
}
|
}
|
||||||
|
|
||||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||||
|
|||||||
BIN
assets/icons/drawer/feedback.png
Normal file
BIN
assets/icons/drawer/feedback.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 366 B |
BIN
assets/icons/drawer/guide.png
Normal file
BIN
assets/icons/drawer/guide.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 468 B |
BIN
assets/icons/drawer/manageusr.png
Normal file
BIN
assets/icons/drawer/manageusr.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 339 B |
BIN
assets/icons/misc/save.png
Normal file
BIN
assets/icons/misc/save.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 330 B |
@ -300,6 +300,7 @@ import 'package:uae_stat/presentation/Screens/charts/chart.dart';
|
|||||||
import 'package:uae_stat/presentation/Screens/charts/screens/chart_screen.dart';
|
import 'package:uae_stat/presentation/Screens/charts/screens/chart_screen.dart';
|
||||||
import 'package:uae_stat/presentation/Screens/demo_home2.dart';
|
import 'package:uae_stat/presentation/Screens/demo_home2.dart';
|
||||||
import 'package:uae_stat/presentation/Screens/online_offline_verification/internet_check.dart';
|
import 'package:uae_stat/presentation/Screens/online_offline_verification/internet_check.dart';
|
||||||
|
import 'package:uae_stat/presentation/routes/auth_routes/pocketbase_service.dart';
|
||||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/getting_started.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';
|
||||||
|
|
||||||
@ -324,20 +325,33 @@ import '../presentation/routes/drawer_routes/Drawer Items/user_guide/features.da
|
|||||||
import '../presentation/routes/drawer_routes/Drawer Items/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 pbService = PocketBaseService();
|
||||||
|
|
||||||
|
Future<String> getInitialRoute() async {
|
||||||
|
bool isLoggedIn = await pbService.loadSession();
|
||||||
|
return isLoggedIn ? '/myhomepage' : '/login';
|
||||||
|
}
|
||||||
|
|
||||||
final GoRouter router = GoRouter(
|
final GoRouter router = GoRouter(
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
//builder: (context, state) => LoginRoute(),
|
//builder: (context, state) => LoginRoute(),
|
||||||
builder: (context, state) => LoginRoute(isLoginScreen: true),
|
builder: (context, state) => LoginRoute(),
|
||||||
),
|
),
|
||||||
|
// GoRoute(
|
||||||
|
// path: '/',
|
||||||
|
// redirect: (context, state) async {
|
||||||
|
// return await getInitialRoute();
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/internetcheck',
|
path: '/internetcheck',
|
||||||
builder: (context, state) => InternetCheck(),
|
builder: (context, state) => InternetCheck(),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/login',
|
path: '/login',
|
||||||
builder: (context, state) => LoginRoute(isLoginScreen: true),
|
builder: (context, state) => LoginRoute(),
|
||||||
//builder: (context, state) => LoginRoute(),
|
//builder: (context, state) => LoginRoute(),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
|
|||||||
@ -8,4 +8,7 @@ abstract class DrawerAssetIconPath {
|
|||||||
static const message = '$_basePath/message.png';
|
static const message = '$_basePath/message.png';
|
||||||
static const scroll = '$_basePath/scroll.png';
|
static const scroll = '$_basePath/scroll.png';
|
||||||
static const manageuser = '$_basePath/manageuser.png';
|
static const manageuser = '$_basePath/manageuser.png';
|
||||||
|
static const manageUser = '$_basePath/manageusr.png';
|
||||||
|
static const guide = '$_basePath/guide.png';
|
||||||
|
static const feedback = '$_basePath/feedback.png';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,4 +9,6 @@ abstract class MiscIconAssetPath {
|
|||||||
static const vector = '$_basePath/vector.png';
|
static const vector = '$_basePath/vector.png';
|
||||||
static const visibleOn = '$_basePath/visible_on.png';
|
static const visibleOn = '$_basePath/visible_on.png';
|
||||||
static const visibilityOff = '$_basePath/visibility_off.png';
|
static const visibilityOff = '$_basePath/visibility_off.png';
|
||||||
|
static const save = '$_basePath/save.png';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -271,7 +271,13 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
'Email ID already exists. Please use a different email.'),
|
'Email ID already exists. Please use a different email.'),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
setState(() {
|
||||||
|
isRegistering =
|
||||||
|
false; // Re-enable the button after error
|
||||||
|
});
|
||||||
|
},
|
||||||
child: Text('OK'),
|
child: Text('OK'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -356,6 +362,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
backgroundColor: Colors.white,
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
body: registrationSuccess
|
body: registrationSuccess
|
||||||
@ -474,8 +481,8 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Padding(
|
: Padding(
|
||||||
padding: const EdgeInsets.only(top: 5.0,bottom: 20, left: 30,right: 30),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 5.0, bottom: 20, left: 30, right: 30),
|
||||||
child: Form(
|
child: Form(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
@ -502,13 +509,23 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
hintText: _showHints[0]
|
hintText: _showHints[0]
|
||||||
? AppLocalizations.of(context)!.register_name
|
? AppLocalizations.of(context)!.register_name
|
||||||
: null,
|
: null,
|
||||||
|
prefixIconConstraints: const BoxConstraints(
|
||||||
|
maxWidth: 25 + 16 + 10,
|
||||||
|
maxHeight: 25 + (8 * 2),
|
||||||
|
),
|
||||||
prefixIcon: Padding(
|
prefixIcon: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 1.0,top:1.0,right:10.0,left:15.0 ), // Adjust the padding as needed
|
padding: const EdgeInsetsDirectional.only(
|
||||||
|
start: 16,
|
||||||
|
end: 10,
|
||||||
|
),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
MiscIconAssetPath.person,
|
MiscIconAssetPath.person,
|
||||||
color: Color(0xFF90B0D5),
|
fit: BoxFit.fitHeight,
|
||||||
|
height: 25,
|
||||||
width: 25,
|
width: 25,
|
||||||
height: 15,
|
color:
|
||||||
|
MyTheme.topicColor(IndicatorTopic.economy)
|
||||||
|
.shade300,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -520,20 +537,29 @@ class _RegisterScreenState extends State<RegisterScreen> {
|
|||||||
// border: OutlineInputBorder(),
|
// border: OutlineInputBorder(),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade400,
|
borderSide: BorderSide(
|
||||||
width: 1), // Enabled border
|
color: MyTheme.topicColor(
|
||||||
),
|
IndicatorTopic.economy)
|
||||||
|
.shade400,
|
||||||
|
width: 1), // Enabled border
|
||||||
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
borderSide: BorderSide(
|
||||||
|
color: Colors.deepPurple,
|
||||||
|
width: 2), // Focused border
|
||||||
),
|
),
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Error border
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Error border
|
||||||
),
|
),
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Match the error color
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Match the error color
|
||||||
),
|
),
|
||||||
counterText: '',
|
counterText: '',
|
||||||
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
||||||
@ -554,32 +580,52 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
.enter_your_email
|
.enter_your_email
|
||||||
: null,
|
: null,
|
||||||
// _showHints[1] ? 'Enter your email' : null,
|
// _showHints[1] ? 'Enter your email' : null,
|
||||||
|
prefixIconConstraints: const BoxConstraints(
|
||||||
|
maxWidth: 25 + 16 + 10,
|
||||||
|
maxHeight: 25 + (8 * 2),
|
||||||
|
),
|
||||||
prefixIcon: Padding(
|
prefixIcon: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 1.0,top:1.0,right:10.0,left:15.0 ), // Adjust the padding as needed
|
padding: const EdgeInsetsDirectional.only(
|
||||||
|
start: 16,
|
||||||
|
end: 10,
|
||||||
|
),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
MiscIconAssetPath.vector,
|
MiscIconAssetPath.vector,
|
||||||
color: Color(0xFF90B0D5),
|
fit: BoxFit.fitHeight,
|
||||||
|
height: 20,
|
||||||
width: 25,
|
width: 25,
|
||||||
height: 15,
|
color:
|
||||||
|
MyTheme.topicColor(IndicatorTopic.economy)
|
||||||
|
.shade100,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// border: OutlineInputBorder(),
|
// border: OutlineInputBorder(),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade400,
|
borderSide: BorderSide(
|
||||||
|
color: MyTheme.topicColor(
|
||||||
|
IndicatorTopic.economy)
|
||||||
|
.shade400,
|
||||||
width: 1),
|
width: 1),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
borderSide: BorderSide(
|
||||||
|
color: Colors.deepPurple,
|
||||||
|
width: 2), // Focused border
|
||||||
),
|
),
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Error border
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Error border
|
||||||
),
|
),
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Match the error color
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Match the error color
|
||||||
),
|
),
|
||||||
counterText: '',
|
counterText: '',
|
||||||
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
||||||
@ -603,15 +649,26 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
.enter_your_password
|
.enter_your_password
|
||||||
: null,
|
: null,
|
||||||
// _showHints[2] ? 'Enter your password' : null,
|
// _showHints[2] ? 'Enter your password' : null,
|
||||||
|
prefixIconConstraints: const BoxConstraints(
|
||||||
|
maxWidth: 25 + 16 + 10,
|
||||||
|
maxHeight: 25 + (8 * 2),
|
||||||
|
),
|
||||||
prefixIcon: Padding(
|
prefixIcon: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 1.0,top:1.0,right:10.0,left:15.0 ), // Adjust the padding as needed
|
padding: const EdgeInsetsDirectional.only(
|
||||||
|
start: 16,
|
||||||
|
end: 10,
|
||||||
|
),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
MiscIconAssetPath.lock,
|
MiscIconAssetPath.lock,
|
||||||
color: Color(0xFF90B0D5),
|
fit: BoxFit.fitHeight,
|
||||||
|
height: 25,
|
||||||
width: 25,
|
width: 25,
|
||||||
height: 15,
|
color:
|
||||||
|
MyTheme.topicColor(IndicatorTopic.economy)
|
||||||
|
.shade300,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// prefixIcon: Icon(
|
// prefixIcon: Icon(
|
||||||
// Icons.lock,
|
// Icons.lock,
|
||||||
// color: Color(0xFF90B0D5),
|
// color: Color(0xFF90B0D5),
|
||||||
@ -626,15 +683,15 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
|
|
||||||
icon: Image.asset(
|
icon: Image.asset(
|
||||||
_obscurePassword
|
_obscurePassword
|
||||||
?MiscIconAssetPath.visibilityOff
|
? MiscIconAssetPath.visibilityOff
|
||||||
:MiscIconAssetPath.visibleOn,
|
: MiscIconAssetPath.visibleOn,
|
||||||
|
|
||||||
color: Color(0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
|
color: Color(
|
||||||
|
0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_obscurePassword = !_obscurePassword;
|
_obscurePassword = !_obscurePassword;
|
||||||
@ -644,20 +701,29 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
// border: OutlineInputBorder(),
|
// border: OutlineInputBorder(),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade400,
|
borderSide: BorderSide(
|
||||||
|
color: MyTheme.topicColor(
|
||||||
|
IndicatorTopic.economy)
|
||||||
|
.shade400,
|
||||||
width: 1),
|
width: 1),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
borderSide: BorderSide(
|
||||||
|
color: Colors.deepPurple,
|
||||||
|
width: 2), // Focused border
|
||||||
),
|
),
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Error border
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Error border
|
||||||
),
|
),
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Match the error color
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Match the error color
|
||||||
),
|
),
|
||||||
|
|
||||||
counterText: '',
|
counterText: '',
|
||||||
@ -678,23 +744,34 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
.register_Confirm_password
|
.register_Confirm_password
|
||||||
: null,
|
: null,
|
||||||
// _showHints[3] ? 'Confirm password' : null,
|
// _showHints[3] ? 'Confirm password' : null,
|
||||||
|
prefixIconConstraints: const BoxConstraints(
|
||||||
|
maxWidth: 25 + 16 + 10,
|
||||||
|
maxHeight: 25 + (8 * 2),
|
||||||
|
),
|
||||||
prefixIcon: Padding(
|
prefixIcon: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 1.0,top:1.0,right:10.0,left:15.0 ), // Adjust the padding as needed
|
padding: const EdgeInsetsDirectional.only(
|
||||||
|
start: 16,
|
||||||
|
end: 10,
|
||||||
|
),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
MiscIconAssetPath.lock,
|
MiscIconAssetPath.lock,
|
||||||
color: Color(0xFF90B0D5),
|
fit: BoxFit.fitHeight,
|
||||||
|
height: 25,
|
||||||
width: 25,
|
width: 25,
|
||||||
height: 15,
|
color:
|
||||||
|
MyTheme.topicColor(IndicatorTopic.economy)
|
||||||
|
.shade300,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
suffixIcon: IconButton(
|
|
||||||
|
|
||||||
|
suffixIcon: IconButton(
|
||||||
icon: Image.asset(
|
icon: Image.asset(
|
||||||
_obscureConfirmPassword
|
_obscureConfirmPassword
|
||||||
?MiscIconAssetPath.visibilityOff
|
? MiscIconAssetPath.visibilityOff
|
||||||
:MiscIconAssetPath.visibleOn,
|
: MiscIconAssetPath.visibleOn,
|
||||||
|
|
||||||
color: Color(0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
|
color: Color(
|
||||||
|
0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly.
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
@ -710,20 +787,29 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
// ),
|
// ),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade400,
|
borderSide: BorderSide(
|
||||||
|
color: MyTheme.topicColor(
|
||||||
|
IndicatorTopic.economy)
|
||||||
|
.shade400,
|
||||||
width: 1),
|
width: 1),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Colors.deepPurple, width: 2), // Focused border
|
borderSide: BorderSide(
|
||||||
|
color: Colors.deepPurple,
|
||||||
|
width: 2), // Focused border
|
||||||
),
|
),
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Error border
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Error border
|
||||||
),
|
),
|
||||||
focusedErrorBorder: OutlineInputBorder(
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
borderSide: BorderSide(color: Color(0xFFb22222), width: 1), // Match the error color
|
borderSide: BorderSide(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
width: 1), // Match the error color
|
||||||
),
|
),
|
||||||
counterText: '',
|
counterText: '',
|
||||||
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
hintStyle: TextStyle(color: Color(0xFFC3C6CB)),
|
||||||
@ -748,7 +834,9 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
side: BorderSide(
|
side: BorderSide(
|
||||||
color: showError ? Color(0xFFD83731) : Color(0xFF92722A),
|
color: showError
|
||||||
|
? Color(0xFFD83731)
|
||||||
|
: Color(0xFF92722A),
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -762,25 +850,31 @@ borderSide: BorderSide(color: MyTheme.topicColor(IndicatorTopic.economy).shade40
|
|||||||
text: AppLocalizations.of(context)!
|
text: AppLocalizations.of(context)!
|
||||||
.terms_conditions,
|
.terms_conditions,
|
||||||
// text: 'Terms & Conditions',
|
// text: 'Terms & Conditions',
|
||||||
style: TextStyle(fontWeight: FontWeight.bold,
|
style: TextStyle(
|
||||||
color: Color(0xFF648CBA),
|
fontWeight: FontWeight.bold,
|
||||||
// Makes the text bold
|
color: Color(0xFF648CBA),
|
||||||
decoration: TextDecoration.underline,
|
// Makes the text bold
|
||||||
decorationColor: Color(0xFF648CBA),
|
decoration:
|
||||||
decorationThickness: 1),
|
TextDecoration.underline,
|
||||||
),
|
decorationColor: Color(0xFF648CBA),
|
||||||
|
decorationThickness: 1),
|
||||||
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: AppLocalizations.of(context)!
|
text: AppLocalizations.of(context)!
|
||||||
.t_and),
|
.t_and),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: AppLocalizations.of(context)!
|
text: AppLocalizations.of(context)!
|
||||||
.privacy_policy,
|
.privacy_policy,
|
||||||
style: TextStyle(fontWeight: FontWeight.bold,
|
style: TextStyle(
|
||||||
color: Color(0xFF648CBA),
|
fontWeight: FontWeight.bold,
|
||||||
decoration: TextDecoration.underline,
|
fontSize: 14,
|
||||||
|
fontFamily: 'Roboto',
|
||||||
|
color: Color(0xFF648CBA),
|
||||||
|
decoration:
|
||||||
|
TextDecoration.underline,
|
||||||
decorationColor: Color(0xFF648CBA),
|
decorationColor: Color(0xFF648CBA),
|
||||||
decorationThickness: 1),
|
decorationThickness: 1),
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: AppLocalizations.of(context)!
|
text: AppLocalizations.of(context)!
|
||||||
.conditions),
|
.conditions),
|
||||||
@ -831,7 +925,8 @@ style: TextStyle(fontWeight: FontWeight.bold,
|
|||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.chevron_right_outlined,
|
Icons.chevron_right_outlined,
|
||||||
color: Colors.white, // Set your desired color here
|
color: Colors
|
||||||
|
.white, // Set your desired color here
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -841,7 +936,7 @@ style: TextStyle(fontWeight: FontWeight.bold,
|
|||||||
Text(
|
Text(
|
||||||
AppLocalizations.of(context)!.account_confirmation,
|
AppLocalizations.of(context)!.account_confirmation,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16, color: Colors.grey[600]),
|
fontSize: 14, color: Colors.grey[600]),
|
||||||
),
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
@ -868,7 +963,8 @@ style: TextStyle(fontWeight: FontWeight.bold,
|
|||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.chevron_right_outlined,
|
Icons.chevron_right_outlined,
|
||||||
color: Colors.white, // Set your desired color here
|
color: Colors
|
||||||
|
.white, // Set your desired color here
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import 'package:image_picker/image_picker.dart';
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:pocketbase/pocketbase.dart';
|
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/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
|
||||||
import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
||||||
|
|
||||||
import '../components/my_bottom_nav_bar.dart';
|
import '../components/my_bottom_nav_bar.dart';
|
||||||
@ -74,7 +75,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
// Regular expression to validate Full Name (no special characters)
|
// Regular expression to validate Full Name (no special characters)
|
||||||
final RegExp _nameRegExp = RegExp(r"^[a-zA-Z\s]+$");
|
final RegExp _nameRegExp = RegExp(r"^[a-zA-Z\s]+$");
|
||||||
late Future<RecordModel> userDetails;
|
late Future<RecordModel> userDetails;
|
||||||
bool _isHoveringDate = false;
|
bool _isHoveringDate = false;
|
||||||
bool _isHoveringDropdown = false;
|
bool _isHoveringDropdown = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -336,435 +337,450 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
appBar: AppBar(
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
backgroundColor: Colors.white,
|
if (didPop) return;
|
||||||
elevation: 0,
|
context.go('/');
|
||||||
leading: IconButton(
|
},
|
||||||
icon: Icon(Icons.arrow_back_ios_new, color: Colors.black),
|
child: Scaffold(
|
||||||
onPressed: () {
|
appBar: AppBar(
|
||||||
context.go('/');
|
backgroundColor: Colors.white,
|
||||||
},
|
elevation: 0,
|
||||||
),
|
leading: IconButton(
|
||||||
title: Text(
|
icon: Icon(Icons.arrow_back_ios_new, color: Colors.black),
|
||||||
'My Profile',
|
|
||||||
style: TextStyle(color: Colors.orange),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.go('/');
|
context.go('/');
|
||||||
},
|
},
|
||||||
child: Text(
|
),
|
||||||
'Logout',
|
title: Text(
|
||||||
style: TextStyle(color: Colors.orange),
|
'My Profile',
|
||||||
|
style: TextStyle(color: Color(0xFF985400)),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.go('/');
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'Logout',
|
||||||
|
style: TextStyle(color: Colors.orange),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
IconButton(
|
||||||
IconButton(
|
icon: Icon(Icons.logout, color: Colors.black),
|
||||||
icon: Icon(Icons.logout, color: Colors.black),
|
onPressed: () {},
|
||||||
onPressed: () {},
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
body: SingleChildScrollView(
|
||||||
body: SingleChildScrollView(
|
child: Form(
|
||||||
child: Form(
|
key: _formKey,
|
||||||
key: _formKey,
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.only(
|
||||||
padding: const EdgeInsets.only(top: 20.0,bottom: 20.0, left: 25,right: 25),
|
top: 20.0, bottom: 20.0, left: 25, right: 25),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// CircleAvatar(
|
// CircleAvatar(
|
||||||
// radius: 50,
|
// radius: 50,
|
||||||
// backgroundImage: _profileImage != null
|
// backgroundImage: _profileImage != null
|
||||||
// ? FileImage(_profileImage!)
|
// ? FileImage(_profileImage!)
|
||||||
// : AssetImage("assets/edit_profile/profile.png")
|
// : AssetImage("assets/edit_profile/profile.png")
|
||||||
// as ImageProvider,
|
// as ImageProvider,
|
||||||
// child: Align(
|
// child: Align(
|
||||||
// alignment: Alignment.bottomRight,
|
// alignment: Alignment.bottomRight,
|
||||||
// child: GestureDetector(
|
// child: GestureDetector(
|
||||||
// onTap: _pickImage, // Call `_pickImage` on tap
|
// onTap: _pickImage, // Call `_pickImage` on tap
|
||||||
// child: CircleAvatar(
|
// child: CircleAvatar(
|
||||||
// radius: 15,
|
// radius: 15,
|
||||||
// backgroundColor: Colors.white,
|
// backgroundColor: Colors.white,
|
||||||
// child: Icon(
|
// child: Icon(
|
||||||
// Icons.camera_alt,
|
// Icons.camera_alt,
|
||||||
// size: 15,
|
// size: 15,
|
||||||
// color: Colors.grey,
|
// color: Colors.grey,
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
|
|
||||||
Stack(
|
Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
// CircleAvatar with the profile image
|
// CircleAvatar with the profile image
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
radius: 50,
|
radius: 50,
|
||||||
backgroundImage: _profileImage != null
|
backgroundImage: _profileImage != null
|
||||||
? FileImage(_profileImage!)
|
? FileImage(_profileImage!)
|
||||||
: AssetImage("assets/edit_profile/profile.png")
|
: AssetImage("assets/edit_profile/profile.png")
|
||||||
as ImageProvider,
|
as ImageProvider,
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: _pickImage, // Call `_pickImage` on tap
|
onTap: _pickImage, // Call `_pickImage` on tap
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
radius: 15,
|
radius: 15,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.camera_alt,
|
Icons.camera_alt,
|
||||||
size: 15,
|
size: 15,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
|
|
||||||
// Conditional loader that shows when _isLoading is true
|
// Conditional loader that shows when _isLoading is true
|
||||||
if (_isLoading)
|
if (_isLoading)
|
||||||
Positioned(
|
Positioned(
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
valueColor:
|
valueColor:
|
||||||
AlwaysStoppedAnimation<Color>(Colors.grey),
|
AlwaysStoppedAnimation<Color>(Colors.grey),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
SizedBox(height: 20),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"User Name",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
TextFormField(
|
|
||||||
controller: _usernameController,
|
|
||||||
focusNode: _focusNodes[0],
|
|
||||||
decoration: InputDecoration(
|
|
||||||
// hintText: _showHints[0] ? 'Enter the User Name' : null,
|
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
enabled: false,
|
|
||||||
),
|
),
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Email ID",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
TextFormField(
|
|
||||||
controller: _emailController,
|
|
||||||
focusNode: _focusNodes[1],
|
|
||||||
decoration: InputDecoration(
|
|
||||||
// hintText:
|
|
||||||
// _showHints[1] ? 'mohammad.hassan@fcsc.gov.ae' : null,
|
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
enabled: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Full Name*",
|
|
||||||
style:
|
|
||||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
TextFormField(
|
|
||||||
enabled: true,
|
|
||||||
validator: (value) {
|
|
||||||
if (value == null || value.isEmpty) {
|
|
||||||
return 'Required';
|
|
||||||
}
|
|
||||||
|
|
||||||
//RegExp(r"^[a-zA-Z\s]+$");
|
SizedBox(height: 20),
|
||||||
final nameRegex = RegExp(
|
|
||||||
r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$");
|
|
||||||
|
|
||||||
if (!nameRegex.hasMatch(value)) {
|
|
||||||
return 'Invalid Characters';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
controller: _fullNameController,
|
|
||||||
focusNode: _focusNodes[2],
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: _showHints[2] ? 'Enter the name' : null,
|
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
counterText: '',
|
|
||||||
),
|
|
||||||
maxLength: 40, // Set the maximum length to 20 characters
|
|
||||||
maxLengthEnforcement: MaxLengthEnforcement.enforced,
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Date of Birth*",
|
|
||||||
style:
|
|
||||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
MouseRegion(
|
|
||||||
onEnter: (_) => setState(() => _isHoveringDate = true),
|
|
||||||
onExit: (_) => setState(() => _isHoveringDate = false),
|
|
||||||
child: TextFormField(
|
|
||||||
controller: _dateController,
|
|
||||||
focusNode: _focusNodes[3],
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
hintText: _showHints[3] ? 'DD/MM/YYYY' : null,
|
|
||||||
//_showHints[3] ? 'Select your Date of Birth' : null,
|
|
||||||
hintStyle: TextStyle(color: Colors.grey),
|
|
||||||
|
|
||||||
suffixIcon: Container(
|
|
||||||
width: 45,
|
|
||||||
padding: EdgeInsets.only(right: 1),
|
|
||||||
alignment: Alignment.center, // Center the icon vertically
|
|
||||||
child: Icon(
|
|
||||||
Icons.keyboard_arrow_down_sharp,
|
|
||||||
color: _isHoveringDate ? Colors.black : Colors.grey,
|
|
||||||
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
readOnly: true,
|
|
||||||
onTap: _pickDate,
|
|
||||||
validator: _validateDob,
|
|
||||||
),),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Country/Region*",
|
|
||||||
style:
|
|
||||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
MouseRegion(
|
|
||||||
onEnter: (_) => setState(() => _isHoveringDropdown = true),
|
|
||||||
onExit: (_) => setState(() => _isHoveringDropdown = false),
|
|
||||||
child: DropdownButtonFormField<String>(
|
|
||||||
value: _selectedCountry,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: OutlineInputBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
labelText: 'Select',
|
|
||||||
),
|
|
||||||
icon: Icon(Icons.keyboard_arrow_down_sharp,
|
|
||||||
color: _isHoveringDropdown ? Colors.black : Colors.grey ),
|
|
||||||
items: _countries
|
|
||||||
.map((item) => DropdownMenuItem<String>(
|
|
||||||
value: item,
|
|
||||||
child: Text(item),
|
|
||||||
))
|
|
||||||
.toList(),
|
|
||||||
onChanged: (String? newValue) {
|
|
||||||
setState(() {
|
|
||||||
_selectedCountry = newValue;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
validator: _validateDropdown,
|
|
||||||
),),
|
|
||||||
SizedBox(height: 20),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Checkbox(
|
|
||||||
value: isChecked,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
isChecked = value ?? false;
|
|
||||||
showError = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
side: BorderSide(
|
|
||||||
color: showError ? Color(0xFFb22222) : Color(0xFF92722A),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
Text.rich(
|
|
||||||
TextSpan(
|
|
||||||
text: 'I agree to the ',
|
|
||||||
style: TextStyle(color: Colors.black),
|
|
||||||
children: [
|
|
||||||
TextSpan(
|
|
||||||
text: 'Terms & Conditions',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Color(0xFF648CBA),
|
|
||||||
decoration: TextDecoration.underline,
|
|
||||||
fontWeight: FontWeight.bold, // Makes the text bold
|
|
||||||
decorationColor: Color(0xFF648CBA),
|
|
||||||
decorationThickness: 1,
|
|
||||||
),
|
|
||||||
recognizer: TapGestureRecognizer()
|
|
||||||
..onTap = () {
|
|
||||||
// Add action for Terms & Conditions tap
|
|
||||||
},
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
text: ' and ',
|
|
||||||
style: TextStyle(color: Colors.black),
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
text: 'Privacy Policy',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Color(0xFF648CBA),
|
|
||||||
decoration: TextDecoration.underline,
|
|
||||||
fontWeight: FontWeight.bold, // Makes the text bold
|
|
||||||
decorationColor: Color(0xFF648CBA),
|
|
||||||
decorationThickness: 1,
|
|
||||||
|
|
||||||
),
|
|
||||||
recognizer: TapGestureRecognizer()
|
|
||||||
..onTap = () {
|
|
||||||
// Add action for Privacy Policy tap
|
|
||||||
},
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
text: ' of FCSC.',
|
|
||||||
style: TextStyle(color: Colors.black),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.start,
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.visible,
|
|
||||||
softWrap: true,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (showError)
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Text(
|
||||||
padding: const EdgeInsets.only(left: 10.0),
|
"User Name",
|
||||||
child: Text(
|
style: TextStyle(
|
||||||
'Please agree to terms and conditions',
|
fontSize: 16,
|
||||||
style: TextStyle(
|
fontWeight: FontWeight.w500,
|
||||||
color: Color(0xFFb22222),
|
color: Colors.grey),
|
||||||
fontSize: 12,
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
TextFormField(
|
||||||
|
controller: _usernameController,
|
||||||
|
focusNode: _focusNodes[0],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
// hintText: _showHints[0] ? 'Enter the User Name' : null,
|
||||||
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
enabled: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Email ID",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
TextFormField(
|
||||||
|
controller: _emailController,
|
||||||
|
focusNode: _focusNodes[1],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
// hintText:
|
||||||
|
// _showHints[1] ? 'mohammad.hassan@fcsc.gov.ae' : null,
|
||||||
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
enabled: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Full Name*",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
TextFormField(
|
||||||
|
enabled: true,
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Required';
|
||||||
|
}
|
||||||
|
|
||||||
|
//RegExp(r"^[a-zA-Z\s]+$");
|
||||||
|
final nameRegex = RegExp(
|
||||||
|
r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$");
|
||||||
|
|
||||||
|
if (!nameRegex.hasMatch(value)) {
|
||||||
|
return 'Invalid Characters';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
controller: _fullNameController,
|
||||||
|
focusNode: _focusNodes[2],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: _showHints[2] ? 'Enter the name' : null,
|
||||||
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
counterText: '',
|
||||||
|
),
|
||||||
|
maxLength: 40, // Set the maximum length to 20 characters
|
||||||
|
maxLengthEnforcement: MaxLengthEnforcement.enforced,
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Date of Birth*",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
MouseRegion(
|
||||||
|
onEnter: (_) => setState(() => _isHoveringDate = true),
|
||||||
|
onExit: (_) => setState(() => _isHoveringDate = false),
|
||||||
|
child: TextFormField(
|
||||||
|
controller: _dateController,
|
||||||
|
focusNode: _focusNodes[3],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
hintText: _showHints[3] ? 'DD/MM/YYYY' : null,
|
||||||
|
//_showHints[3] ? 'Select your Date of Birth' : null,
|
||||||
|
hintStyle: TextStyle(color: Colors.grey),
|
||||||
|
|
||||||
|
suffixIcon: Container(
|
||||||
|
width: 45,
|
||||||
|
padding: EdgeInsets.only(right: 1),
|
||||||
|
alignment:
|
||||||
|
Alignment.center, // Center the icon vertically
|
||||||
|
child: Icon(
|
||||||
|
Icons.keyboard_arrow_down_sharp,
|
||||||
|
color: _isHoveringDate ? Colors.black : Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
readOnly: true,
|
||||||
|
onTap: _pickDate,
|
||||||
|
validator: _validateDob,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Country/Region*",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
MouseRegion(
|
||||||
|
onEnter: (_) => setState(() => _isHoveringDropdown = true),
|
||||||
|
onExit: (_) => setState(() => _isHoveringDropdown = false),
|
||||||
|
child: DropdownButtonFormField<String>(
|
||||||
|
value: _selectedCountry,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
labelText: 'Select',
|
||||||
|
),
|
||||||
|
icon: Icon(Icons.keyboard_arrow_down_sharp,
|
||||||
|
color:
|
||||||
|
_isHoveringDropdown ? Colors.black : Colors.grey),
|
||||||
|
items: _countries
|
||||||
|
.map((item) => DropdownMenuItem<String>(
|
||||||
|
value: item,
|
||||||
|
child: Text(item),
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
_selectedCountry = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
validator: _validateDropdown,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: isChecked,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
isChecked = value ?? false;
|
||||||
|
showError = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
side: BorderSide(
|
||||||
|
color:
|
||||||
|
showError ? Color(0xFFb22222) : Color(0xFF92722A),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
text: 'I agree to the ',
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: 'Terms & Conditions',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFF648CBA),
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
fontWeight: FontWeight
|
||||||
|
.bold, // Makes the text bold
|
||||||
|
decorationColor: Color(0xFF648CBA),
|
||||||
|
decorationThickness: 1,
|
||||||
|
),
|
||||||
|
recognizer: TapGestureRecognizer()
|
||||||
|
..onTap = () {
|
||||||
|
// Add action for Terms & Conditions tap
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: ' and ',
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: 'Privacy Policy',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFF648CBA),
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
fontWeight: FontWeight
|
||||||
|
.bold, // Makes the text bold
|
||||||
|
decorationColor: Color(0xFF648CBA),
|
||||||
|
decorationThickness: 1,
|
||||||
|
),
|
||||||
|
recognizer: TapGestureRecognizer()
|
||||||
|
..onTap = () {
|
||||||
|
// Add action for Privacy Policy tap
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: ' of FCSC.',
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.visible,
|
||||||
|
softWrap: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
if (showError)
|
||||||
Center(
|
Row(
|
||||||
child: GestureDetector(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
onTap: () {
|
children: [
|
||||||
final userId = widget.userId;
|
Padding(
|
||||||
final email = _emailController.text;
|
padding: const EdgeInsets.only(left: 10.0),
|
||||||
|
child: Text(
|
||||||
|
'Please agree to terms and conditions',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xFFb22222),
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Center(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
final userId = widget.userId;
|
||||||
|
final email = _emailController.text;
|
||||||
|
|
||||||
context.go('/createNewPw/$userId/$email');
|
context.go('/createNewPw/$userId/$email');
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Change Password',
|
'Change Password',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Color(0xFF648CBA),
|
color: Color(0xFF648CBA),
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
fontFamily: 'Roboto',
|
fontFamily: 'Roboto',
|
||||||
// decoration: TextDecoration.underline),
|
// decoration: TextDecoration.underline),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(height: 20),
|
||||||
SizedBox(height: 20),
|
// ElevatedButton.icon(
|
||||||
// ElevatedButton.icon(
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if ((_formKey.currentState?.validate() ?? false) && (isChecked)) {
|
if ((_formKey.currentState?.validate() ?? false) &&
|
||||||
_formKey.currentState?.save();
|
(isChecked)) {
|
||||||
showConfirmationDialog(context);
|
_formKey.currentState?.save();
|
||||||
} else {
|
showConfirmationDialog(context);
|
||||||
setState(() {
|
} else {
|
||||||
showError = !isChecked; // Show error if the checkbox is not checked
|
setState(() {
|
||||||
});
|
showError =
|
||||||
}
|
!isChecked; // Show error if the checkbox is not checked
|
||||||
},
|
});
|
||||||
style: ElevatedButton.styleFrom(
|
}
|
||||||
backgroundColor: Color(0xFF92722A),
|
},
|
||||||
minimumSize: Size(double.infinity, 50),
|
style: ElevatedButton.styleFrom(
|
||||||
shape: RoundedRectangleBorder(
|
backgroundColor: Color(0xFF92722A),
|
||||||
borderRadius: BorderRadius.circular(8),
|
minimumSize: Size(double.infinity, 50),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
child: Row(
|
||||||
child: Row(
|
mainAxisAlignment:
|
||||||
mainAxisAlignment: MainAxisAlignment.center, // Center the content
|
MainAxisAlignment.center, // Center the content
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Save',
|
'Save',
|
||||||
style: TextStyle(color: Colors.white),
|
style: TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8), // Add space between text and icon
|
SizedBox(width: 8), // Add space between text and icon
|
||||||
Icon(
|
Image.asset(
|
||||||
Icons.save_outlined,
|
MiscIconAssetPath.save,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
width: 20,
|
||||||
],
|
height: 20,
|
||||||
),
|
),
|
||||||
)
|
],
|
||||||
|
),
|
||||||
],
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
//bottomNavigationBar: MyBottomNavBar(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ 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/my_bottom_nav_bar.dart';
|
||||||
import 'package:uae_stat/presentation/components/space.dart';
|
import 'package:uae_stat/presentation/components/space.dart';
|
||||||
import 'package:uae_stat/presentation/components/themed_text_field.dart';
|
import 'package:uae_stat/presentation/components/themed_text_field.dart';
|
||||||
|
import 'package:uae_stat/presentation/routes/auth_routes/pocketbase_service.dart';
|
||||||
import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import '../../Screens/auth_verification/registration.dart';
|
import '../../Screens/auth_verification/registration.dart';
|
||||||
@ -27,10 +28,11 @@ import '../../components/my_toggle.dart';
|
|||||||
|
|
||||||
class LoginRoute extends HookConsumerWidget {
|
class LoginRoute extends HookConsumerWidget {
|
||||||
final pb = PocketBase('https://pb.venbait.in');
|
final pb = PocketBase('https://pb.venbait.in');
|
||||||
|
final _pbService = PocketBaseService();
|
||||||
// final _pb = PocketBase('http://127.0.0.1:8090');
|
// final _pb = PocketBase('http://127.0.0.1:8090');
|
||||||
final bool isLoginScreen; // Pass `true` if this is the login screen
|
// final bool isLoginScreen; // Pass `true` if this is the login screen
|
||||||
LoginRoute({Key? key, required this.isLoginScreen}) : super(key: key);
|
// LoginRoute({Key? key, required this.isLoginScreen}) : super(key: key);
|
||||||
// LoginRoute({super.key});
|
LoginRoute({super.key});
|
||||||
dynamic userData;
|
dynamic userData;
|
||||||
String? role;
|
String? role;
|
||||||
|
|
||||||
@ -96,52 +98,91 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
final forgotPwFormKey = GlobalKey<FormState>();
|
final forgotPwFormKey = GlobalKey<FormState>();
|
||||||
final email = await showDialog<String>(
|
final email = await showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (dialogCtx) => AlertDialog(
|
builder: (dialogCtx) => SizedBox(
|
||||||
title: Text(
|
// width: 850, // Increase dialog width
|
||||||
context.translate(
|
child: AlertDialog(
|
||||||
'Reset Password',
|
shape: RoundedRectangleBorder(
|
||||||
'إعادة تعيين كلمة المرور',
|
borderRadius: BorderRadius.circular(20), // Rounded corners
|
||||||
),
|
),
|
||||||
|
elevation: 10,
|
||||||
|
shadowColor: Colors.black12,
|
||||||
|
title: Text(
|
||||||
|
context.translate(
|
||||||
|
'Reset Password',
|
||||||
|
'إعادة تعيين كلمة المرور',
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
color: Color(0xFF898C81),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
content: Form(
|
||||||
|
key: forgotPwFormKey,
|
||||||
|
child: TextFormField(
|
||||||
|
validator: FieldValidator.email(),
|
||||||
|
controller: emailCtl,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: context.translate(
|
||||||
|
'Email address',
|
||||||
|
'عنوان البريد الإلكتروني',
|
||||||
|
),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Color(0xFF898C81), // For label text color
|
||||||
|
// fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: Navigator.of(dialogCtx, rootNavigator: true).pop,
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
// backgroundColor: Colors.white, // Background color
|
||||||
|
foregroundColor: Color(0xFF92722A), // Font (text) color
|
||||||
|
side: BorderSide(
|
||||||
|
color: Color(0xFF92722A)), // Border outline color
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(8), // Optional: Rounded corners
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 16, vertical: 12), // Optional: Padding
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
context.translate(
|
||||||
|
'Return',
|
||||||
|
'يعود',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
final isValid = forgotPwFormKey.currentState!.validate();
|
||||||
|
if (!isValid) return;
|
||||||
|
Navigator.of(dialogCtx, rootNavigator: true).pop(
|
||||||
|
emailCtl.text,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Color(0xFF92722A),
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 15, vertical: 15), // Optional: Adjusts size
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
// Optional: Adds rounded corners
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
context.translate(
|
||||||
|
'Send Reset Email',
|
||||||
|
'إرسال إعادة تعيين البريد الإلكتروني',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
content: Form(
|
|
||||||
key: forgotPwFormKey,
|
|
||||||
child: TextFormField(
|
|
||||||
validator: FieldValidator.email(),
|
|
||||||
controller: emailCtl,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: context.translate(
|
|
||||||
'Email address',
|
|
||||||
'عنوان البريد الإلكتروني',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: Navigator.of(dialogCtx, rootNavigator: true).pop,
|
|
||||||
child: Text(
|
|
||||||
context.translate(
|
|
||||||
'Return',
|
|
||||||
'يعود',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
final isValid = forgotPwFormKey.currentState!.validate();
|
|
||||||
if (!isValid) return;
|
|
||||||
Navigator.of(dialogCtx, rootNavigator: true).pop(
|
|
||||||
emailCtl.text,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
context.translate(
|
|
||||||
'Send Reset Email',
|
|
||||||
'إرسال إعادة تعيين البريد الإلكتروني',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (email == null) return;
|
if (email == null) return;
|
||||||
@ -177,7 +218,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: Color(0xFF985400),
|
color: Color(0xFF985400),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -361,7 +402,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
6.horizontalSpace,
|
6.horizontalSpace,
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.chevron_right_outlined,
|
Icons.chevron_right_outlined,
|
||||||
color: Colors.white, // Set your desired color here
|
color: Colors.white, // Set your desired color here
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -390,8 +431,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
validator: (text) {
|
validator: (text) {
|
||||||
if (text == null || text.isEmpty) {
|
if (text == null || text.isEmpty) {
|
||||||
return context.translate('Required', 'مطلوب');
|
return context.translate('Required', 'مطلوب');
|
||||||
}
|
} else if (text.length < 8) {
|
||||||
else 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);
|
||||||
@ -403,12 +443,14 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
imgPath: MiscIconAssetPath.lock,
|
imgPath: MiscIconAssetPath.lock,
|
||||||
controller: pwCtl,
|
controller: pwCtl,
|
||||||
isObscurable: true,
|
isObscurable: true,
|
||||||
|
|
||||||
),
|
),
|
||||||
// 6.verticalSpace,
|
// 6.verticalSpace,
|
||||||
Align(
|
Padding(
|
||||||
alignment: AlignmentDirectional.topEnd,
|
padding: EdgeInsets.zero,
|
||||||
child: forgotPwBtn,
|
child: Align(
|
||||||
|
alignment: AlignmentDirectional.topEnd,
|
||||||
|
child: forgotPwBtn,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
10.verticalSpace,
|
10.verticalSpace,
|
||||||
loginBtn,
|
loginBtn,
|
||||||
@ -460,7 +502,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
'Roboto',
|
'Roboto',
|
||||||
'NotoKufi',
|
'NotoKufi',
|
||||||
),
|
),
|
||||||
fontSize: 18,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
@ -482,8 +524,8 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
'سجل الان',
|
'سجل الان',
|
||||||
),
|
),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Color(0xFF985400),
|
color: Color(0xFF985400),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -574,7 +616,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
helloAndPleaseLoginTexts,
|
helloAndPleaseLoginTexts,
|
||||||
42.verticalSpace,
|
42.verticalSpace,
|
||||||
form,
|
form,
|
||||||
20.verticalSpace,
|
15.verticalSpace,
|
||||||
dontHaveAnAccountRegisterBtn,
|
dontHaveAnAccountRegisterBtn,
|
||||||
20.verticalSpace,
|
20.verticalSpace,
|
||||||
// continueAsGuestBtn,
|
// continueAsGuestBtn,
|
||||||
@ -588,7 +630,7 @@ class LoginRoute extends HookConsumerWidget {
|
|||||||
// );
|
// );
|
||||||
// return bgScaffold;
|
// return bgScaffold;
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: !isLoginScreen, // Allow back navigation only if not login screen
|
canPop: false, // Allow back navigation only if not login screen
|
||||||
onPopInvokedWithResult: (didPop, result) {
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
if (didPop) return;
|
if (didPop) return;
|
||||||
_showExitConfirmation(context); // Show exit confirmation dialog
|
_showExitConfirmation(context); // Show exit confirmation dialog
|
||||||
|
|||||||
66
lib/presentation/routes/auth_routes/pocketbase_service.dart
Normal file
66
lib/presentation/routes/auth_routes/pocketbase_service.dart
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import 'package:pocketbase/pocketbase.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class PocketBaseService {
|
||||||
|
final PocketBase pb = PocketBase('https://pb.venbait.in');
|
||||||
|
|
||||||
|
// Save session to local storage
|
||||||
|
Future<void> saveSession() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setString('pb_auth', pb.authStore.token);
|
||||||
|
await prefs.setString('pb_user', pb.authStore.model.toJson());
|
||||||
|
await prefs.setInt('pb_auth_time', DateTime.now().millisecondsSinceEpoch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load session from local storage
|
||||||
|
Future<bool> loadSession() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final token = prefs.getString('pb_auth');
|
||||||
|
final userJson = prefs.getString('pb_user');
|
||||||
|
|
||||||
|
if (token != null && userJson != null) {
|
||||||
|
pb.authStore
|
||||||
|
.save(token, RecordModel.fromJson(userJson as Map<String, dynamic>));
|
||||||
|
|
||||||
|
if (!pb.authStore.isValid || isSessionExpired(prefs)) {
|
||||||
|
await clearSession();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the session is expired (4 days)
|
||||||
|
bool isSessionExpired(SharedPreferences prefs) {
|
||||||
|
final savedTime = prefs.getInt('pb_auth_time') ?? 0;
|
||||||
|
final currentTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
const sessionDuration = Duration(days: 4);
|
||||||
|
return (currentTime - savedTime) > sessionDuration.inMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User login
|
||||||
|
Future<bool> loginUser(String email, String password) async {
|
||||||
|
try {
|
||||||
|
await pb.collection('users').authWithPassword(email, password);
|
||||||
|
await saveSession();
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// User logout
|
||||||
|
Future<void> logoutUser() async {
|
||||||
|
pb.authStore.clear();
|
||||||
|
await clearSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear session from local storage
|
||||||
|
Future<void> clearSession() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.remove('pb_auth');
|
||||||
|
await prefs.remove('pb_user');
|
||||||
|
await prefs.remove('pb_auth_time');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -207,7 +207,7 @@ class EconomyStatsWidget extends ConsumerStatefulWidget {
|
|||||||
|
|
||||||
class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||||
List<dynamic> data = [];
|
List<dynamic> data = [];
|
||||||
final _pb = PocketBase('https://pb.venbait.in');
|
final _pb = PocketBase('https://pb.venbait.in');
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
|
||||||
final GlobalKey cardTopicKey = GlobalKey();
|
final GlobalKey cardTopicKey = GlobalKey();
|
||||||
@ -216,14 +216,13 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
late List<TargetFocus> homeTargets;
|
late List<TargetFocus> homeTargets;
|
||||||
late List<TargetFocus> previousHomeTargets;
|
late List<TargetFocus> previousHomeTargets;
|
||||||
|
|
||||||
|
|
||||||
void handleSkip() {
|
void handleSkip() {
|
||||||
tutorialCoachMark.skip();
|
tutorialCoachMark.skip();
|
||||||
debugPrint('Skip clicked');
|
debugPrint('Skip clicked');
|
||||||
ref.read(chartsTourProvider.notifier).state = true;
|
ref.read(chartsTourProvider.notifier).state = true;
|
||||||
ref.read(previousChartsTourProvider.notifier).state = true;
|
ref.read(previousChartsTourProvider.notifier).state = true;
|
||||||
ref.read(homeTourProvider.notifier).state = true;
|
ref.read(homeTourProvider.notifier).state = true;
|
||||||
ref.read( previousHomeTourProvider.notifier).state = true;
|
ref.read(previousHomeTourProvider.notifier).state = true;
|
||||||
ref.read(scaffoldTourProvider.notifier).state = true;
|
ref.read(scaffoldTourProvider.notifier).state = true;
|
||||||
ref.read(previousScaffoldTourProvider.notifier).state = true;
|
ref.read(previousScaffoldTourProvider.notifier).state = true;
|
||||||
}
|
}
|
||||||
@ -257,7 +256,8 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
ref.read(homeTourProvider.notifier).state = true;
|
ref.read(homeTourProvider.notifier).state = true;
|
||||||
ref.read(chartsTourProvider.notifier).state = false;
|
ref.read(chartsTourProvider.notifier).state = false;
|
||||||
debugPrint('Home Tutorial Finished');
|
debugPrint('Home Tutorial Finished');
|
||||||
context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
|
context.go(
|
||||||
|
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
|
||||||
},
|
},
|
||||||
)..show(context: context);
|
)..show(context: context);
|
||||||
} else if (!previousHomeTour) {
|
} else if (!previousHomeTour) {
|
||||||
@ -271,16 +271,16 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
onFinish: () {
|
onFinish: () {
|
||||||
ref.read(previousHomeTourProvider.notifier).state = true;
|
ref.read(previousHomeTourProvider.notifier).state = true;
|
||||||
debugPrint('Previous Home Tutorial Finished');
|
debugPrint('Previous Home Tutorial Finished');
|
||||||
context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
|
context.go(
|
||||||
|
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
|
||||||
},
|
},
|
||||||
)..show(context: context);
|
)..show(context: context);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initTarget(){
|
void _initTarget() {
|
||||||
final double screenWidth = MediaQuery.of(context).size.width;
|
final double screenWidth = MediaQuery.of(context).size.width;
|
||||||
homeTargets=[
|
homeTargets = [
|
||||||
TargetFocus(
|
TargetFocus(
|
||||||
identify: 'cardTopicKey',
|
identify: 'cardTopicKey',
|
||||||
keyTarget: cardTopicKey,
|
keyTarget: cardTopicKey,
|
||||||
@ -298,7 +298,7 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
align: ContentAlign.bottom,
|
align: ContentAlign.bottom,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: MediaQuery.of(context).size.height*0.70,
|
height: MediaQuery.of(context).size.height * 0.70,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
@ -310,7 +310,8 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 10), // Adjust the value as needed
|
padding: const EdgeInsets.only(
|
||||||
|
right: 10), // Adjust the value as needed
|
||||||
child: Text(
|
child: Text(
|
||||||
'1/7',
|
'1/7',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@ -320,7 +321,9 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5,),
|
SizedBox(
|
||||||
|
height: 5,
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
@ -350,12 +353,14 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Color(0xFF7DAFBC),
|
color: Color(0xFF7DAFBC),
|
||||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1),
|
border: Border.all(
|
||||||
|
color: Color(0xFF7DAFBC), width: 1),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
iconSize: 20,
|
iconSize: 20,
|
||||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
icon: const Icon(Icons.arrow_forward,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
tutorialCoachMark.next();
|
tutorialCoachMark.next();
|
||||||
},
|
},
|
||||||
@ -366,8 +371,7 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -399,16 +403,17 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
// targetPosition:TargetPosition(),
|
// targetPosition:TargetPosition(),
|
||||||
contents: [
|
contents: [
|
||||||
createTargetContent(
|
createTargetContent(
|
||||||
text:AppLocalizations.of(context)!.economy,
|
text: AppLocalizations.of(context)!.economy,
|
||||||
alignment: ContentAlign.bottom,
|
alignment: ContentAlign.bottom,
|
||||||
gap: 0,
|
gap: 0,
|
||||||
space: 43,),
|
space: 43,
|
||||||
|
),
|
||||||
TargetContent(
|
TargetContent(
|
||||||
align: ContentAlign.bottom,
|
align: ContentAlign.bottom,
|
||||||
child:
|
child: SizedBox(
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: MediaQuery.of(context).size.height *0.5, // Set an appropriate height for the Stack
|
height: MediaQuery.of(context).size.height *
|
||||||
|
0.5, // Set an appropriate height for the Stack
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
@ -419,23 +424,22 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
children: [
|
children: [
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child:Padding(padding: EdgeInsets.only(right: 10),
|
child: Padding(
|
||||||
child:
|
padding: EdgeInsets.only(right: 10),
|
||||||
Text(
|
child: Text(
|
||||||
'2/7',
|
'2/7',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
const SizedBox(height: 3),
|
const SizedBox(height: 3),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () =>handleSkip(),
|
onPressed: () => handleSkip(),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
@ -457,11 +461,13 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(color: Colors.white, width: 2.0),
|
border: Border.all(
|
||||||
|
color: Colors.white, width: 2.0),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
iconSize: 20,
|
iconSize: 20,
|
||||||
icon: const Icon(Icons.arrow_back, color: Colors.white),
|
icon: const Icon(Icons.arrow_back,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
tutorialCoachMark.previous();
|
tutorialCoachMark.previous();
|
||||||
},
|
},
|
||||||
@ -472,11 +478,13 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Color(0xFF7DAFBC),
|
color: Color(0xFF7DAFBC),
|
||||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1),
|
border: Border.all(
|
||||||
|
color: Color(0xFF7DAFBC), width: 1),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
iconSize: 20,
|
iconSize: 20,
|
||||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
icon: const Icon(Icons.arrow_forward,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
tutorialCoachMark.next();
|
tutorialCoachMark.next();
|
||||||
},
|
},
|
||||||
@ -535,9 +543,9 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initPreviousTarget(){
|
void _initPreviousTarget() {
|
||||||
final double screenWidth = MediaQuery.of(context).size.width;
|
final double screenWidth = MediaQuery.of(context).size.width;
|
||||||
previousHomeTargets=[
|
previousHomeTargets = [
|
||||||
TargetFocus(
|
TargetFocus(
|
||||||
identify: 'cardsKey',
|
identify: 'cardsKey',
|
||||||
keyTarget: cardsKey,
|
keyTarget: cardsKey,
|
||||||
@ -546,16 +554,17 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
paddingFocus: 6,
|
paddingFocus: 6,
|
||||||
contents: [
|
contents: [
|
||||||
createTargetContent(
|
createTargetContent(
|
||||||
text:AppLocalizations.of(context)!.economy,
|
text: AppLocalizations.of(context)!.economy,
|
||||||
alignment: ContentAlign.bottom,
|
alignment: ContentAlign.bottom,
|
||||||
gap: 0,
|
gap: 0,
|
||||||
space: 43,),
|
space: 43,
|
||||||
|
),
|
||||||
TargetContent(
|
TargetContent(
|
||||||
align: ContentAlign.bottom,
|
align: ContentAlign.bottom,
|
||||||
child:
|
child: SizedBox(
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: MediaQuery.of(context).size.height *0.5, // Set an appropriate height for the Stack
|
height: MediaQuery.of(context).size.height *
|
||||||
|
0.5, // Set an appropriate height for the Stack
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
@ -566,23 +575,24 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
children: [
|
children: [
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child:Padding(padding: EdgeInsets.only(right: 10),
|
child: Padding(
|
||||||
child:
|
padding: EdgeInsets.only(right: 10),
|
||||||
Text(
|
child: Text(
|
||||||
'2/7',
|
'2/7',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)),
|
||||||
|
SizedBox(
|
||||||
|
height: 5,
|
||||||
),
|
),
|
||||||
SizedBox(height: 5,),
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () =>handleSkip(),
|
onPressed: () => handleSkip(),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
@ -600,17 +610,18 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
|
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(color: Colors.white, width: 2.0),
|
border: Border.all(
|
||||||
|
color: Colors.white, width: 2.0),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: const Icon(Icons.arrow_back, color: Colors.white),
|
icon: const Icon(Icons.arrow_back,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
tutorialCoachMark.next();
|
tutorialCoachMark.next();
|
||||||
},
|
},
|
||||||
@ -621,15 +632,24 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Color(0xFF7DAFBC),
|
color: Color(0xFF7DAFBC),
|
||||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1.5),
|
border: Border.all(
|
||||||
|
color: Color(0xFF7DAFBC),
|
||||||
|
width: 1.5),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
iconSize: 20,
|
iconSize: 20,
|
||||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
icon: const Icon(Icons.arrow_forward,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ref.read(previousHomeTourProvider.notifier).state=true;
|
ref
|
||||||
ref.read(chartsTourProvider.notifier).state=false;
|
.read(previousHomeTourProvider
|
||||||
context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
|
.notifier)
|
||||||
|
.state = true;
|
||||||
|
ref
|
||||||
|
.read(chartsTourProvider.notifier)
|
||||||
|
.state = false;
|
||||||
|
context.go(
|
||||||
|
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
|
||||||
tutorialCoachMark.finish();
|
tutorialCoachMark.finish();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -673,7 +693,7 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
paddingFocus: 16,
|
paddingFocus: 16,
|
||||||
contents: [
|
contents: [
|
||||||
createTargetContent(
|
createTargetContent(
|
||||||
text:AppLocalizations.of(context)!.home_topic,
|
text: AppLocalizations.of(context)!.home_topic,
|
||||||
alignment: ContentAlign.bottom,
|
alignment: ContentAlign.bottom,
|
||||||
gap: 0,
|
gap: 0,
|
||||||
space: 43,
|
space: 43,
|
||||||
@ -682,7 +702,7 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
align: ContentAlign.bottom,
|
align: ContentAlign.bottom,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: MediaQuery.of(context).size.height*0.69,
|
height: MediaQuery.of(context).size.height * 0.69,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
@ -694,7 +714,7 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
Align(
|
Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:EdgeInsets.only(right: 10),
|
padding: EdgeInsets.only(right: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
'1/7',
|
'1/7',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@ -735,11 +755,13 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: Color(0xFF7DAFBC),
|
color: Color(0xFF7DAFBC),
|
||||||
border: Border.all(color: Color(0xFF7DAFBC), width: 1.5),
|
border: Border.all(
|
||||||
|
color: Color(0xFF7DAFBC), width: 1.5),
|
||||||
),
|
),
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
iconSize: 20,
|
iconSize: 20,
|
||||||
icon: const Icon(Icons.arrow_forward, color: Colors.white),
|
icon: const Icon(Icons.arrow_forward,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
tutorialCoachMark.previous();
|
tutorialCoachMark.previous();
|
||||||
},
|
},
|
||||||
@ -777,15 +799,13 @@ final _pb = PocketBase('https://pb.venbait.in');
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
@override
|
void initState() {
|
||||||
void initState() {
|
super.initState();
|
||||||
super.initState();
|
final locale = ref.read(localeProvider);
|
||||||
final locale = ref.read(localeProvider);
|
fetchData(locale?.languageCode ?? 'en');
|
||||||
fetchData(locale?.languageCode ?? 'en');
|
_fetchUserData();
|
||||||
_fetchUserData();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// @override
|
// @override
|
||||||
// void didChangeDependencies() {
|
// void didChangeDependencies() {
|
||||||
@ -795,43 +815,38 @@ _fetchUserData();
|
|||||||
// fetchData(locale); // Pass the locale to the fetchData method
|
// fetchData(locale); // Pass the locale to the fetchData method
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
Future<String?> getUserId() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
return prefs.getString('userId'); // Retrieve the userId
|
||||||
|
}
|
||||||
|
|
||||||
Future<String?> getUserId() async {
|
Future<void> _fetchUserData() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
try {
|
||||||
return prefs.getString('userId'); // Retrieve the userId
|
final userId = await getUserId();
|
||||||
}
|
print('EDIT PROFILE isPageLoad');
|
||||||
|
final adminAuth = await _pb.admins
|
||||||
|
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||||
Future<void> _fetchUserData() async {
|
final adminToken = adminAuth.token;
|
||||||
try {
|
print('adminToken- $adminToken');
|
||||||
final userId = await getUserId();
|
final userDetailsResponse = await _pb.collection('users').getOne(
|
||||||
print('EDIT PROFILE isPageLoad');
|
userId!,
|
||||||
final adminAuth = await _pb.admins
|
headers: {
|
||||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
'Authorization': 'Bearer $adminToken',
|
||||||
final adminToken = adminAuth.token;
|
},
|
||||||
print('adminToken- $adminToken');
|
);
|
||||||
final userDetailsResponse = await _pb.collection('users').getOne(
|
final loginCount = userDetailsResponse.data['login_count'];
|
||||||
userId!,
|
print(loginCount);
|
||||||
headers: {
|
if (loginCount == 1) {
|
||||||
'Authorization': 'Bearer $adminToken',
|
setState(() {
|
||||||
},
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
);
|
_starTourRender();
|
||||||
final loginCount = userDetailsResponse.data['login_count'];
|
});
|
||||||
print(loginCount);
|
});
|
||||||
if (loginCount == 1) {
|
}
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
} catch (e) {
|
||||||
_starTourRender();
|
print('Error fetching user details: $e');
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
print('Error fetching user details: $e');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future<void> fetchData(locale) async {
|
Future<void> fetchData(locale) async {
|
||||||
const baseUrl = 'https://pb.venbait.in/api/getHomePageData';
|
const baseUrl = 'https://pb.venbait.in/api/getHomePageData';
|
||||||
@ -940,7 +955,7 @@ print('Error fetching user details: $e');
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
RoundedCornerContainer(
|
RoundedCornerContainer(
|
||||||
key: mainTopic['main_topic'] =='ECONOMY'
|
key: mainTopic['main_topic'] == 'ECONOMY'
|
||||||
? cardTopicKey
|
? cardTopicKey
|
||||||
: null,
|
: null,
|
||||||
text: mainTopic['main_topic'],
|
text: mainTopic['main_topic'],
|
||||||
@ -954,7 +969,7 @@ print('Error fetching user details: $e');
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: myheight / 4.8, // Set dynamic height
|
height: myheight / 4.8, // Set dynamic height
|
||||||
child: Container(
|
child: Container(
|
||||||
key:mainTopic['main_topic'] == 'ECONOMY'
|
key: mainTopic['main_topic'] == 'ECONOMY'
|
||||||
? cardsKey
|
? cardsKey
|
||||||
: null,
|
: null,
|
||||||
// color: Colors.grey[200], // Set a background color for the scrollable container
|
// color: Colors.grey[200], // Set a background color for the scrollable container
|
||||||
@ -1176,7 +1191,6 @@ class InfoCard extends StatelessWidget {
|
|||||||
final encodedTitle = Uri.encodeComponent(title);
|
final encodedTitle = Uri.encodeComponent(title);
|
||||||
final encodedKey = Uri.encodeQueryComponent('home');
|
final encodedKey = Uri.encodeQueryComponent('home');
|
||||||
|
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.go(
|
context.go(
|
||||||
@ -1263,4 +1277,4 @@ class InfoCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:pocketbase/pocketbase.dart';
|
import 'package:pocketbase/pocketbase.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.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';
|
||||||
|
|
||||||
class EditProfile extends StatefulWidget {
|
class EditProfile extends StatefulWidget {
|
||||||
@ -424,11 +425,11 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseScaffold(
|
return BaseScaffold(
|
||||||
title: Text(AppLocalizations.of(context)!.my_profile),
|
title: Text(AppLocalizations.of(context)!.my_profile,
|
||||||
|
style: TextStyle(color: Color(0xFF985400)),),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 10.0, right: 10.0, top: 3.0),
|
padding: const EdgeInsets.only(left: 10.0, right: 10.0, top: 3.0),
|
||||||
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
@ -436,8 +437,9 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
// padding: const EdgeInsets.all(20.0),
|
// padding: const EdgeInsets.all(20.0),
|
||||||
padding: const EdgeInsets.only(top: 20.0,bottom: 20.0, left: 25,right: 25),
|
padding: const EdgeInsets.only(
|
||||||
child: isPageLoad
|
top: 20.0, bottom: 20.0, left: 25, right: 25),
|
||||||
|
child: isPageLoad
|
||||||
? Center(
|
? Center(
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
)
|
)
|
||||||
@ -727,11 +729,11 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
suffixIcon: Container(
|
suffixIcon: Container(
|
||||||
width: 45,
|
width: 45,
|
||||||
padding: EdgeInsets.only(right: 1),
|
padding: EdgeInsets.only(right: 1),
|
||||||
alignment: Alignment.center, // Center the icon vertically
|
alignment: Alignment
|
||||||
|
.center, // Center the icon vertically
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.keyboard_arrow_down_sharp,
|
Icons.keyboard_arrow_down_sharp,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
enabled: !_isProfileCompleted,
|
enabled: !_isProfileCompleted,
|
||||||
@ -755,8 +757,10 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
MouseRegion(
|
MouseRegion(
|
||||||
onEnter: (_) => setState(() => _isHoveringDropdown = true),
|
onEnter: (_) =>
|
||||||
onExit: (_) => setState(() => _isHoveringDropdown = false),
|
setState(() => _isHoveringDropdown = true),
|
||||||
|
onExit: (_) =>
|
||||||
|
setState(() => _isHoveringDropdown = false),
|
||||||
child: DropdownButtonFormField<String>(
|
child: DropdownButtonFormField<String>(
|
||||||
value: _selectedCountry,
|
value: _selectedCountry,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@ -766,7 +770,9 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
labelText: 'Select',
|
labelText: 'Select',
|
||||||
),
|
),
|
||||||
icon: Icon(Icons.keyboard_arrow_down_sharp,
|
icon: Icon(Icons.keyboard_arrow_down_sharp,
|
||||||
color: _isHoveringDropdown ? Colors.black : Colors.grey ),
|
color: _isHoveringDropdown
|
||||||
|
? Colors.black
|
||||||
|
: Colors.grey),
|
||||||
items: _countries
|
items: _countries
|
||||||
.map(
|
.map(
|
||||||
(item) => DropdownMenuItem<String>(
|
(item) => DropdownMenuItem<String>(
|
||||||
@ -781,7 +787,8 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
validator: _validateDropdown,
|
validator: _validateDropdown,
|
||||||
),),
|
),
|
||||||
|
),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
if (!_isProfileCompleted) // Conditional rendering
|
if (!_isProfileCompleted) // Conditional rendering
|
||||||
Column(
|
Column(
|
||||||
@ -827,7 +834,8 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
.terms_conditions,
|
.terms_conditions,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
// color: Colors.blue,
|
// color: Colors.blue,
|
||||||
color: Color(0xFF648CBA),
|
color:
|
||||||
|
Color(0xFF648CBA),
|
||||||
decoration:
|
decoration:
|
||||||
TextDecoration
|
TextDecoration
|
||||||
.underline,
|
.underline,
|
||||||
@ -854,7 +862,7 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
.privacy_policy,
|
.privacy_policy,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
// color: Colors.blue,
|
// color: Colors.blue,
|
||||||
color: Color(0xFF648CBA),
|
color: Color(0xFF648CBA),
|
||||||
decoration:
|
decoration:
|
||||||
TextDecoration
|
TextDecoration
|
||||||
.underline,
|
.underline,
|
||||||
@ -911,7 +919,8 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
final email = _emailController.text;
|
final email = _emailController.text;
|
||||||
context.go('/createNewPw/$userId/$email?key=editProfile');
|
context.go(
|
||||||
|
'/createNewPw/$userId/$email?key=editProfile');
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
AppLocalizations.of(context)!
|
AppLocalizations.of(context)!
|
||||||
@ -949,14 +958,14 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
// ),
|
// ),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if ((_formKey.currentState?.validate() ?? false) && (isChecked)) {
|
// if ((_formKey.currentState?.validate() ?? false) && (isChecked)) {
|
||||||
_formKey.currentState?.save();
|
// _formKey.currentState?.save();
|
||||||
showConfirmationDialog(context);
|
showConfirmationDialog(context);
|
||||||
} else {
|
// } else {
|
||||||
setState(() {
|
// setState(() {
|
||||||
showError = !isChecked; // Show error if the checkbox is not checked
|
// showError = !isChecked; // Show error if the checkbox is not checked
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Color(0xFF92722A),
|
backgroundColor: Color(0xFF92722A),
|
||||||
@ -969,13 +978,15 @@ class _EditProfileState extends State<EditProfile> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center, // Center the content
|
mainAxisAlignment: MainAxisAlignment.center, // Center the content
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Save',
|
AppLocalizations.of(context)!.save,
|
||||||
style: TextStyle(color: Colors.white),
|
style: TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8), // Add space between text and icon
|
SizedBox(width: 8), // Add space between text and icon
|
||||||
Icon(
|
Image.asset(
|
||||||
Icons.save_outlined,
|
MiscIconAssetPath.save,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
||||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bottom_bar_asset_icon_path.dart';
|
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bottom_bar_asset_icon_path.dart';
|
||||||
|
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/drawer_asset_icon_path.dart';
|
||||||
|
|
||||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||||
import 'package:uae_stat/presentation/components/my_toggle.dart';
|
import 'package:uae_stat/presentation/components/my_toggle.dart';
|
||||||
@ -734,15 +735,25 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
),
|
),
|
||||||
if (userId != 'guest')
|
if (userId != 'guest')
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.feedback),
|
leading: Image.asset(
|
||||||
|
DrawerAssetIconPath.feedback,
|
||||||
|
color: Colors.black ,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
// title: const Text('Feedback'),
|
// title: const Text('Feedback'),
|
||||||
title: Text(AppLocalizations.of(context)!.feedback_title),
|
title: Text(AppLocalizations.of(context)!.feedback_title),
|
||||||
onTap: () => context.go('/feedback'),
|
onTap: () => context.go('/feedback'),
|
||||||
),
|
),
|
||||||
if (role == 'admin')
|
if (role == 'admin')
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.manage_accounts),
|
leading: Image.asset(
|
||||||
// title: Text('Manage User'),
|
DrawerAssetIconPath.manageUser,
|
||||||
|
color: Colors.black ,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
// title: Text('Manage User'),
|
||||||
title: Text(
|
title: Text(
|
||||||
AppLocalizations.of(context)!.manage_user,
|
AppLocalizations.of(context)!.manage_user,
|
||||||
),
|
),
|
||||||
@ -754,7 +765,12 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
onTap: () => context.go('/bookmark'),
|
onTap: () => context.go('/bookmark'),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.book),
|
leading: Image.asset(
|
||||||
|
DrawerAssetIconPath.guide,
|
||||||
|
color: Colors.black ,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
// title: const Text('User Guide'),
|
// title: const Text('User Guide'),
|
||||||
title: Text(AppLocalizations.of(context)!.guide_title),
|
title: Text(AppLocalizations.of(context)!.guide_title),
|
||||||
onTap: () => context.go('/user-guide'),
|
onTap: () => context.go('/user-guide'),
|
||||||
|
|||||||
@ -2,7 +2,7 @@ name: uae_stat
|
|||||||
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
|
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
#version: 0.5.10
|
#version: 0.5.10
|
||||||
version: 1.0.6+7
|
version: 1.0.8+9
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.2.3 <4.0.0"
|
sdk: ">=3.2.3 <4.0.0"
|
||||||
@ -120,6 +120,10 @@ flutter:
|
|||||||
- assets/icons/misc/vector.png
|
- assets/icons/misc/vector.png
|
||||||
- assets/icons/misc/visible_on.png
|
- assets/icons/misc/visible_on.png
|
||||||
- assets/icons/misc/visibility_off.png
|
- assets/icons/misc/visibility_off.png
|
||||||
|
- assets/icons/misc/save.png
|
||||||
|
- assets/icons/drawer/guide.png
|
||||||
|
- assets/icons/drawer/feedback.png
|
||||||
|
- assets/icons/drawer/manageusr.png
|
||||||
|
|
||||||
fonts:
|
fonts:
|
||||||
- family: Segoe
|
- family: Segoe
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user