From 3776ba1c01ff6e594727a7e8a2e8eb7fff05191f Mon Sep 17 00:00:00 2001 From: VINISTAN Date: Thu, 19 Dec 2024 14:21:55 +0530 Subject: [PATCH 1/4] router issue fixed --- .run/main.dart.run.xml | 2 +- lib/config/my_router.dart | 13 +- .../auth_verification/registration.dart | 42 +- .../routes/auth_routes/login_route.dart | 401 +++++++++--------- .../drawer_routes/custom_drawer_routes.dart | 4 +- 5 files changed, 230 insertions(+), 232 deletions(-) diff --git a/.run/main.dart.run.xml b/.run/main.dart.run.xml index 4a58a7c9..4767aff8 100644 --- a/.run/main.dart.run.xml +++ b/.run/main.dart.run.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index cdfe3b13..b3cad353 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -301,6 +301,7 @@ import '../presentation/Screens/auth_verification/changepassword.dart'; import '../presentation/Screens/auth_verification/confirm_password.dart'; import '../presentation/Screens/auth_verification/create_new_pw.dart'; import '../presentation/Screens/auth_verification/otp_verification.dart'; +import '../presentation/Screens/auth_verification/registration.dart'; import '../presentation/Screens/profilepage.dart'; import '../presentation/routes/auth_routes/login_route.dart'; import '../presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; @@ -311,13 +312,21 @@ final GoRouter router = GoRouter( routes: [ GoRoute( path: '/', -//builder: (context, state) => LoginRoute(), - builder: (context, state) => MyHomePage(), +builder: (context, state) => LoginRoute(), + //builder: (context, state) => MyHomePage(), ), GoRoute( path: '/myhomepage', builder: (context, state) => MyHomePage(), ), + GoRoute( + path: '/login', + builder: (context, state) => LoginRoute(), + ), + GoRoute( + path: '/registration', + builder: (context, state) => RegisterScreen(), + ), GoRoute( path: '/mailverification', builder: (context, state) => EmailVerificationScreen( diff --git a/lib/presentation/Screens/auth_verification/registration.dart b/lib/presentation/Screens/auth_verification/registration.dart index 97204028..94158760 100644 --- a/lib/presentation/Screens/auth_verification/registration.dart +++ b/lib/presentation/Screens/auth_verification/registration.dart @@ -582,8 +582,8 @@ class _RegisterScreenState extends State { fontSize: 16, color: Colors.white), ), SizedBox(width: 8), - Icon(Icons.arrow_forward, - color: Colors.white), + Icon(Icons.arrow_forward_ios, + color: Colors.white,size: 16,), ], ), ), @@ -599,6 +599,7 @@ class _RegisterScreenState extends State { width: screenwidth / 1.3, child: ElevatedButton( onPressed: () { + context.go('/login'); // Add your login logic here }, style: ElevatedButton.styleFrom( @@ -625,31 +626,20 @@ class _RegisterScreenState extends State { // ], // ), - child: GestureDetector( - onTap: () { - // Navigate to LoginRoute - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => LoginRoute()), - // MaterialPageRoute(builder: (context) => LoginRoute(userId: userID)), - ); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Login", - style: TextStyle( - fontSize: 16, - color: Colors.white, - ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Login", + style: TextStyle( + fontSize: 16, + color: Colors.white, ), - SizedBox(width: 8), - Icon(Icons.arrow_forward, - color: Colors.white), - ], - ), + ), + SizedBox(width: 8), + Icon(Icons.arrow_forward_ios, + color: Colors.white,size: 16,), + ], ), ), ), diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index cbf28f0a..49e86082 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -740,206 +740,205 @@ class _LoginRouteState extends State { ), ), ); -<<<<<<< HEAD -======= - final form = Form( - key: formKey, - child: Column( - children: [ - ThemedFormField( - hintText: context.translate( - 'Email', - 'بريد إلكتروني', - ), - validator: FieldValidator.email(), - imgPath: MiscIconAssetPath.person, - controller: emailCtl, - ), - 15.verticalSpace, - ThemedFormField( - validator: (text) { - if (text!.length < 8) { - return 'The password must be at least 8 characters'; - } - return FieldValidator.password(minLength: 8)(text); - }, - hintText: context.translate( - 'Password', - 'كلمة المرور', - ), - imgPath: MiscIconAssetPath.lock, - controller: pwCtl, - isObscurable: true, - ), - // 6.verticalSpace, - Align( - alignment: AlignmentDirectional.topEnd, - child: forgotPwBtn, - ), - 10.verticalSpace, - loginBtn, - ], - ), - ); - final helloAndPleaseLoginTexts = Column( - children: [ - Text( - context.translate( - 'Hello Again!', - 'مرحبا مجددا!', - ), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 40, - fontWeight: FontWeight.w300, - ), - ), - 10.verticalSpace, - Text( - context.translate( - 'Please login to access UAE’s key official statistics', - 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة', - ), - textAlign: TextAlign.center, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 18, - color: const Color(0xff898C81), - fontWeight: FontWeight.w700, - ), - ), - ], - ); - final dontHaveAnAccountRegisterBtn = TextButton( - onPressed: () => { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => RegisterScreen()), - ), - }, - child: Text.rich( - textAlign: TextAlign.center, - TextSpan( - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 18, - fontWeight: FontWeight.bold, - ), - children: [ - TextSpan( - text: context.translate( - 'Don\'t have an account? ', - 'ليس لديك حساب؟', - ), - style: const TextStyle( - color: Color(0xff898C81), - ), - ), - const TextSpan( - text: ' ', - ), - TextSpan( - text: context.translate( - 'Register Now', - 'سجل الان', - ), - style: TextStyle( - color: MyTheme.topicColor(IndicatorTopic.economy).shade600, - ), - ), - ], - ), - ), - ); - final continueAsGuestBtn = SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: () => context - .go('/${context.language}/${BottomNavBarItem.home.routePath}'), - style: ButtonStyle( - shape: WidgetStatePropertyAll( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - padding: const WidgetStatePropertyAll( - EdgeInsets.symmetric(vertical: 10.5), - ), - textStyle: WidgetStatePropertyAll( - TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - backgroundColor: WidgetStatePropertyAll( - MyTheme.topicColor(IndicatorTopic.environment), - ), - foregroundColor: const WidgetStatePropertyAll( - Colors.white, - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - context.translate( - 'Continue as Guest', - 'استمر كضيف', - ), - ), - 6.horizontalSpace, - const Icon(Icons.chevron_right_outlined), - ], - ), - ), - ); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - ); - final screenWidth = MediaQuery.of(context).size.width; - final listViewHorizontalPadding = - screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2; - final scaffoldBody = ListView( - padding: EdgeInsets.symmetric( - horizontal: listViewHorizontalPadding.toDouble(), - ), - children: [ - 36.verticalSpace, - const Align( - alignment: AlignmentDirectional.topEnd, - child: LangToggle(), - ), - 16.verticalSpace, - helloAndPleaseLoginTexts, - 42.verticalSpace, - form, - 20.verticalSpace, - dontHaveAnAccountRegisterBtn, - 36.verticalSpace, - continueAsGuestBtn, - 72.verticalSpace, - fcscBanner, - ], - ); - final bgScaffold = Scaffold( - backgroundColor: Colors.white, - body: SafeArea(child: scaffoldBody), - ); - return bgScaffold; ->>>>>>> b0c5ebce3deb7da2aa24b0ea5ffe684df7dfb7bf + +// final form = Form( +// key: formKey, +// child: Column( +// children: [ +// ThemedFormField( +// hintText: context.translate( +// 'Email', +// 'بريد إلكتروني', +// ), +// validator: FieldValidator.email(), +// imgPath: MiscIconAssetPath.person, +// controller: emailCtl, +// ), +// 15.verticalSpace, +// ThemedFormField( +// validator: (text) { +// if (text!.length < 8) { +// return 'The password must be at least 8 characters'; +// } +// return FieldValidator.password(minLength: 8)(text); +// }, +// hintText: context.translate( +// 'Password', +// 'كلمة المرور', +// ), +// imgPath: MiscIconAssetPath.lock, +// controller: pwCtl, +// isObscurable: true, +// ), +// // 6.verticalSpace, +// Align( +// alignment: AlignmentDirectional.topEnd, +// child: forgotPwBtn, +// ), +// 10.verticalSpace, +// loginBtn, +// ], +// ), +// ); +// final helloAndPleaseLoginTexts = Column( +// children: [ +// Text( +// context.translate( +// 'Hello Again!', +// 'مرحبا مجددا!', +// ), +// style: TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 40, +// fontWeight: FontWeight.w300, +// ), +// ), +// 10.verticalSpace, +// Text( +// context.translate( +// 'Please login to access UAE’s key official statistics', +// 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة', +// ), +// textAlign: TextAlign.center, +// style: TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 18, +// color: const Color(0xff898C81), +// fontWeight: FontWeight.w700, +// ), +// ), +// ], +// ); +// final dontHaveAnAccountRegisterBtn = TextButton( +// onPressed: () => { +// Navigator.push( +// context, +// MaterialPageRoute(builder: (context) => RegisterScreen()), +// ), +// }, +// child: Text.rich( +// textAlign: TextAlign.center, +// TextSpan( +// style: TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 18, +// fontWeight: FontWeight.bold, +// ), +// children: [ +// TextSpan( +// text: context.translate( +// 'Don\'t have an account? ', +// 'ليس لديك حساب؟', +// ), +// style: const TextStyle( +// color: Color(0xff898C81), +// ), +// ), +// const TextSpan( +// text: ' ', +// ), +// TextSpan( +// text: context.translate( +// 'Register Now', +// 'سجل الان', +// ), +// style: TextStyle( +// color: MyTheme.topicColor(IndicatorTopic.economy).shade600, +// ), +// ), +// ], +// ), +// ), +// ); +// final continueAsGuestBtn = SizedBox( +// width: double.infinity, +// child: ElevatedButton( +// onPressed: () => context +// .go('/${context.language}/${BottomNavBarItem.home.routePath}'), +// style: ButtonStyle( +// shape: WidgetStatePropertyAll( +// RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(10), +// ), +// ), +// padding: const WidgetStatePropertyAll( +// EdgeInsets.symmetric(vertical: 10.5), +// ), +// textStyle: WidgetStatePropertyAll( +// TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 16, +// fontWeight: FontWeight.w600, +// ), +// ), +// backgroundColor: WidgetStatePropertyAll( +// MyTheme.topicColor(IndicatorTopic.environment), +// ), +// foregroundColor: const WidgetStatePropertyAll( +// Colors.white, +// ), +// ), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Text( +// context.translate( +// 'Continue as Guest', +// 'استمر كضيف', +// ), +// ), +// 6.horizontalSpace, +// const Icon(Icons.chevron_right_outlined), +// ], +// ), +// ), +// ); +// final fcscBanner = Image.asset( +// BannerAssetPath.fcsc, +// height: 56, +// ); +// final screenWidth = MediaQuery.of(context).size.width; +// final listViewHorizontalPadding = +// screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2; +// final scaffoldBody = ListView( +// padding: EdgeInsets.symmetric( +// horizontal: listViewHorizontalPadding.toDouble(), +// ), +// children: [ +// 36.verticalSpace, +// const Align( +// alignment: AlignmentDirectional.topEnd, +// child: LangToggle(), +// ), +// 16.verticalSpace, +// helloAndPleaseLoginTexts, +// 42.verticalSpace, +// form, +// 20.verticalSpace, +// dontHaveAnAccountRegisterBtn, +// 36.verticalSpace, +// continueAsGuestBtn, +// 72.verticalSpace, +// fcscBanner, +// ], +// ); +// final bgScaffold = Scaffold( +// backgroundColor: Colors.white, +// body: SafeArea(child: scaffoldBody), +// ); +// return bgScaffold; +// >>>>>>> b0c5ebce3deb7da2aa24b0ea5ffe684df7dfb7bf } } diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index ba1d5bd7..cdd32697 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -137,7 +137,7 @@ class BaseScaffold extends StatelessWidget { //Map the current route to the selected index int _getSelectedIndex(String route) { switch (route) { - case '/': + case '/myhomepage': return 0; case '/about': return 1; @@ -154,7 +154,7 @@ class BaseScaffold extends StatelessWidget { void _onItemTapped(BuildContext context, int index) { switch (index) { case 0: - context.go('/'); + context.go('/myhomepage'); break; case 1: context.go('/about'); From 4e15e0b87e4d8d69eb16e3dae57c31495ca2da3e Mon Sep 17 00:00:00 2001 From: Kalonkarthik Date: Thu, 19 Dec 2024 14:31:38 +0530 Subject: [PATCH 2/4] User Guide updated --- .run/main.dart.run.xml | 2 +- android/gradle.properties | 1 + lib/config/my_router.dart | 13 + .../routes/auth_routes/login_route.dart | 402 +++++++++--------- .../Drawer Items/user_guide/features.dart | 291 +++++++++++++ .../Drawer Items/user_guide/textRich.dart | 110 +++++ .../Drawer Items/user_guide/user_guide.dart | 168 ++++++++ .../drawer_routes/custom_drawer_routes.dart | 26 +- 8 files changed, 803 insertions(+), 210 deletions(-) create mode 100644 lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart create mode 100644 lib/presentation/routes/drawer_routes/Drawer Items/user_guide/textRich.dart create mode 100644 lib/presentation/routes/drawer_routes/Drawer Items/user_guide/user_guide.dart diff --git a/.run/main.dart.run.xml b/.run/main.dart.run.xml index 4a58a7c9..4767aff8 100644 --- a/.run/main.dart.run.xml +++ b/.run/main.dart.run.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/android/gradle.properties b/android/gradle.properties index 3b5b324f..7f5b17ec 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true +org.gradle.java.home=C:\\Program Files\\Eclipse Adoptium\\jdk-17.0.13.11-hotspot diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index cdfe3b13..4402c031 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -305,6 +305,8 @@ import '../presentation/Screens/profilepage.dart'; import '../presentation/routes/auth_routes/login_route.dart'; import '../presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; import '../presentation/routes/drawer_routes/Drawer Items/feedback.dart'; +import '../presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart'; +import '../presentation/routes/drawer_routes/Drawer Items/user_guide/user_guide.dart'; import '../presentation/routes/drawer_routes/Drawer Items/manage_users.dart'; final GoRouter router = GoRouter( @@ -355,12 +357,23 @@ final GoRouter router = GoRouter( path: '/feedback', builder: (context, state) => FeedbackForm(), ), + //Sub route GoRoute( path: '/profile', builder: (context, state) => ProfileScreen( userId: '', ), ), + GoRoute( + path: '/user-guide', + builder: (context, state) => UserGuide(), + routes: [ + GoRoute(path: '/features', + name: 'features', + builder: (context, state) => AboutFCSC(), + ), + ], + ), // GoRoute( // path: '/manageuser', // builder: (context, state) { diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index cbf28f0a..b67e1dc1 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -740,206 +740,206 @@ class _LoginRouteState extends State { ), ), ); -<<<<<<< HEAD -======= - final form = Form( - key: formKey, - child: Column( - children: [ - ThemedFormField( - hintText: context.translate( - 'Email', - 'بريد إلكتروني', - ), - validator: FieldValidator.email(), - imgPath: MiscIconAssetPath.person, - controller: emailCtl, - ), - 15.verticalSpace, - ThemedFormField( - validator: (text) { - if (text!.length < 8) { - return 'The password must be at least 8 characters'; - } - return FieldValidator.password(minLength: 8)(text); - }, - hintText: context.translate( - 'Password', - 'كلمة المرور', - ), - imgPath: MiscIconAssetPath.lock, - controller: pwCtl, - isObscurable: true, - ), - // 6.verticalSpace, - Align( - alignment: AlignmentDirectional.topEnd, - child: forgotPwBtn, - ), - 10.verticalSpace, - loginBtn, - ], - ), - ); - final helloAndPleaseLoginTexts = Column( - children: [ - Text( - context.translate( - 'Hello Again!', - 'مرحبا مجددا!', - ), - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 40, - fontWeight: FontWeight.w300, - ), - ), - 10.verticalSpace, - Text( - context.translate( - 'Please login to access UAE’s key official statistics', - 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة', - ), - textAlign: TextAlign.center, - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 18, - color: const Color(0xff898C81), - fontWeight: FontWeight.w700, - ), - ), - ], - ); - final dontHaveAnAccountRegisterBtn = TextButton( - onPressed: () => { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => RegisterScreen()), - ), - }, - child: Text.rich( - textAlign: TextAlign.center, - TextSpan( - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 18, - fontWeight: FontWeight.bold, - ), - children: [ - TextSpan( - text: context.translate( - 'Don\'t have an account? ', - 'ليس لديك حساب؟', - ), - style: const TextStyle( - color: Color(0xff898C81), - ), - ), - const TextSpan( - text: ' ', - ), - TextSpan( - text: context.translate( - 'Register Now', - 'سجل الان', - ), - style: TextStyle( - color: MyTheme.topicColor(IndicatorTopic.economy).shade600, - ), - ), - ], - ), - ), - ); - final continueAsGuestBtn = SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: () => context - .go('/${context.language}/${BottomNavBarItem.home.routePath}'), - style: ButtonStyle( - shape: WidgetStatePropertyAll( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - padding: const WidgetStatePropertyAll( - EdgeInsets.symmetric(vertical: 10.5), - ), - textStyle: WidgetStatePropertyAll( - TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - backgroundColor: WidgetStatePropertyAll( - MyTheme.topicColor(IndicatorTopic.environment), - ), - foregroundColor: const WidgetStatePropertyAll( - Colors.white, - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - context.translate( - 'Continue as Guest', - 'استمر كضيف', - ), - ), - 6.horizontalSpace, - const Icon(Icons.chevron_right_outlined), - ], - ), - ), - ); - final fcscBanner = Image.asset( - BannerAssetPath.fcsc, - height: 56, - ); - final screenWidth = MediaQuery.of(context).size.width; - final listViewHorizontalPadding = - screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2; - final scaffoldBody = ListView( - padding: EdgeInsets.symmetric( - horizontal: listViewHorizontalPadding.toDouble(), - ), - children: [ - 36.verticalSpace, - const Align( - alignment: AlignmentDirectional.topEnd, - child: LangToggle(), - ), - 16.verticalSpace, - helloAndPleaseLoginTexts, - 42.verticalSpace, - form, - 20.verticalSpace, - dontHaveAnAccountRegisterBtn, - 36.verticalSpace, - continueAsGuestBtn, - 72.verticalSpace, - fcscBanner, - ], - ); - final bgScaffold = Scaffold( - backgroundColor: Colors.white, - body: SafeArea(child: scaffoldBody), - ); - return bgScaffold; ->>>>>>> b0c5ebce3deb7da2aa24b0ea5ffe684df7dfb7bf +// <<<<<<< HEAD +// ======= +// final form = Form( +// key: formKey, +// child: Column( +// children: [ +// ThemedFormField( +// hintText: context.translate( +// 'Email', +// 'بريد إلكتروني', +// ), +// validator: FieldValidator.email(), +// imgPath: MiscIconAssetPath.person, +// controller: emailCtl, +// ), +// 15.verticalSpace, +// ThemedFormField( +// validator: (text) { +// if (text!.length < 8) { +// return 'The password must be at least 8 characters'; +// } +// return FieldValidator.password(minLength: 8)(text); +// }, +// hintText: context.translate( +// 'Password', +// 'كلمة المرور', +// ), +// imgPath: MiscIconAssetPath.lock, +// controller: pwCtl, +// isObscurable: true, +// ), +// // 6.verticalSpace, +// Align( +// alignment: AlignmentDirectional.topEnd, +// child: forgotPwBtn, +// ), +// 10.verticalSpace, +// loginBtn, +// ], +// ), +// ); +// final helloAndPleaseLoginTexts = Column( +// children: [ +// Text( +// context.translate( +// 'Hello Again!', +// 'مرحبا مجددا!', +// ), +// style: TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 40, +// fontWeight: FontWeight.w300, +// ), +// ), +// 10.verticalSpace, +// Text( +// context.translate( +// 'Please login to access UAE’s key official statistics', +// 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة', +// ), +// textAlign: TextAlign.center, +// style: TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 18, +// color: const Color(0xff898C81), +// fontWeight: FontWeight.w700, +// ), +// ), +// ], +// ); +// final dontHaveAnAccountRegisterBtn = TextButton( +// onPressed: () => { +// Navigator.push( +// context, +// MaterialPageRoute(builder: (context) => RegisterScreen()), +// ), +// }, +// child: Text.rich( +// textAlign: TextAlign.center, +// TextSpan( +// style: TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 18, +// fontWeight: FontWeight.bold, +// ), +// children: [ +// TextSpan( +// text: context.translate( +// 'Don\'t have an account? ', +// 'ليس لديك حساب؟', +// ), +// style: const TextStyle( +// color: Color(0xff898C81), +// ), +// ), +// const TextSpan( +// text: ' ', +// ), +// TextSpan( +// text: context.translate( +// 'Register Now', +// 'سجل الان', +// ), +// style: TextStyle( +// color: MyTheme.topicColor(IndicatorTopic.economy).shade600, +// ), +// ), +// ], +// ), +// ), +// ); +// final continueAsGuestBtn = SizedBox( +// width: double.infinity, +// child: ElevatedButton( +// onPressed: () => context +// .go('/${context.language}/${BottomNavBarItem.home.routePath}'), +// style: ButtonStyle( +// shape: WidgetStatePropertyAll( +// RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(10), +// ), +// ), +// padding: const WidgetStatePropertyAll( +// EdgeInsets.symmetric(vertical: 10.5), +// ), +// textStyle: WidgetStatePropertyAll( +// TextStyle( +// fontFamily: context.translate( +// 'Roboto', +// 'NotoKufi', +// ), +// fontSize: 16, +// fontWeight: FontWeight.w600, +// ), +// ), +// backgroundColor: WidgetStatePropertyAll( +// MyTheme.topicColor(IndicatorTopic.environment), +// ), +// foregroundColor: const WidgetStatePropertyAll( +// Colors.white, +// ), +// ), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// Text( +// context.translate( +// 'Continue as Guest', +// 'استمر كضيف', +// ), +// ), +// 6.horizontalSpace, +// const Icon(Icons.chevron_right_outlined), +// ], +// ), +// ), +// ); +// final fcscBanner = Image.asset( +// BannerAssetPath.fcsc, +// height: 56, +// ); +// final screenWidth = MediaQuery.of(context).size.width; +// final listViewHorizontalPadding = +// screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2; +// final scaffoldBody = ListView( +// padding: EdgeInsets.symmetric( +// horizontal: listViewHorizontalPadding.toDouble(), +// ), +// children: [ +// 36.verticalSpace, +// const Align( +// alignment: AlignmentDirectional.topEnd, +// child: LangToggle(), +// ), +// 16.verticalSpace, +// helloAndPleaseLoginTexts, +// 42.verticalSpace, +// form, +// 20.verticalSpace, +// dontHaveAnAccountRegisterBtn, +// 36.verticalSpace, +// continueAsGuestBtn, +// 72.verticalSpace, +// fcscBanner, +// ], +// ); +// final bgScaffold = Scaffold( +// backgroundColor: Colors.white, +// body: SafeArea(child: scaffoldBody), +// ); +// return bgScaffold; +// >>>>>>> b0c5ebce3deb7da2aa24b0ea5ffe684df7dfb7bf } } diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart new file mode 100644 index 00000000..a77bd894 --- /dev/null +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/features.dart @@ -0,0 +1,291 @@ +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/Drawer Items/user_guide/textRich.dart'; +import 'package:uae_stat/presentation/components/space.dart'; +import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; + +class AboutFCSC extends HookConsumerWidget { + const AboutFCSC({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final Color tColor=const Color(0xFF265E84); + final fcscBanner = Image.asset( + BannerAssetPath.fcsc, + height: 56, + alignment:Alignment.center, + ); + return BaseScaffold( + title: const Text('Features'), + + body: Scrollbar( + thumbVisibility: true, + thickness: 8, + radius: Radius.circular(10), + interactive: true, + child: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.only(left: 14.0,right: 16.0, bottom: 16.0), + color: const Color(0xFFD9D9D9), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildRichText([ + createTextSpan( + 'Using Features\n', + fontSize: 20, + color: tColor, + fontWeight: FontWeight.w600, + height: 2, + ), + createTextSpan( + 'When a user clicks on a category, expand or open a new page it to show a list of sub-categories or articles under that section. e.g., under "Using Features", we should see articles like:\n\n', + fontWeight: FontWeight.w400, + ), + createTextSpan( + '1.How to use the Dashboard.\n2.Managing Notifications.\n3.Customizing Preferences.', + height: 1.7, + ), + + createTextSpan( + '\n\nGetting Started with FCSC App', + fontSize: 17, + color:tColor, + fontWeight: FontWeight.w500, + ), + ]), + QuestionAnswerScrollView(), + + ExpandableRichText( + maxLines: 5, + textSpans: [ + createTextSpan( + 'What to Do if Your Register is Pending Approval?\n', + fontSize: 20, + fontWeight: FontWeight.w500, + color: tColor, + ), + createTextSpan( + fontWeight: FontWeight.w400, + 'When you register for the FCSC App, your account may require approval from an administrator before you can start using the app. Follow this guide to understand the process and how to check your registration status.\n', + ), + createTextSpan( + 'Step 1\n', + fontSize: 17, + fontWeight: FontWeight.w600, + color: tColor, + height: 2, + ), + createTextSpan( + 'Complete Your Registration', + fontWeight: FontWeight.w500, + color:tColor, + spacingBottom: 2, + height: 0.8 + ), + createTextSpan( + + fontWeight: FontWeight.w400, + height: 1.4, + spacingBottom: 2, + '1.After entering your details during the registration process, you will receive a confirmation message indicating that your registration has been submitted.\n' + '2.Your registration will be in a "Pending Approval" state until an administrator reviews and approves your request.', + ), + createTextSpan( + 'Step 2\n', + fontSize: 16, + fontWeight: FontWeight.w600, + color:tColor, + height: 2, + ), + createTextSpan( + 'What Happens During Admin Approval?', + spacingBottom: 2, + height: 0.8, + color: tColor, + ), + createTextSpan('1.The administrator will review your details to ensure they meet the necessary criteria\n2.This process typically takes [X amount of time]. You will be notified via email once your registration is approved.\n3.You may receive an email asking for additional information or clarifications if needed.\n\n', + fontWeight: FontWeight.w400, + ), + createTextSpan( + 'Step 3\n', + fontSize: 17, + fontWeight: FontWeight.w600, + color: tColor, + height: 2, + ), + + createTextSpan( + 'How to Check Your Registration Status?', + spacingBottom: 2, + height: 0.8, + color: tColor, + ), + + createTextSpan('1. While waiting for approval, you can check the status of your registration by following these steps:\n', + fontWeight: FontWeight.w400, + ), + + createTextSpan( + ' • Login to the FCSC App: ', + spacingTop: 1, + height: 0.7, + color: tColor, + ), + createTextSpan( + 'Even while your registration is pending, you can still log in using your email and password.', + fontWeight: FontWeight.w400, + ), + createTextSpan( + ' • View Your Dashboard: ', + spacingTop: 2, + height: 0.5, + color: tColor, + ), createTextSpan( + 'Once logged in, you will see a message on your dashboard indicating that your account is still under review. This message will look like: Your registration is pending admin approval. You will be notified once your account is approved', + fontWeight: FontWeight.w400, + ), createTextSpan( + ' • Notifications: ', + spacingTop: 2, + height: 0.5, + color: tColor, + ), createTextSpan( + 'Keep an eye on your email inbox. You will receive a notification when your account is approved and ready for use.\n\n', + fontWeight: FontWeight.w400, + ), + + createTextSpan( + 'Step 4\n', + fontSize: 16, + fontWeight: FontWeight.w600, + color:tColor, + height: 2, + ), + + createTextSpan( + 'What Happens After Approval?', + spacingBottom: 2, + height: 0.8, + color: tColor, + ), + createTextSpan('1.Once your registration is approved, you will receive an email notification confirming your account activation.\n2. You can then log in and access all the features of the FCSC App without any restrictions.\n\n', + fontWeight: FontWeight.w400, + ), + createTextSpan( + 'Step 5\n', + fontSize: 16, + fontWeight: FontWeight.w600, + color:tColor, + height: 2, + ), + + createTextSpan( + "Still Haven't Heard Back?", + spacingBottom: 2, + height: 0.8, + color: tColor, + ), + + + createTextSpan( + '1.If you haven’t received approval after the expected time, you can contact FCSC Support by clicking [Support Link] or sending an email to [support@fcsc.gov.ae].\n2. Provide your registration details and ask for an update on your approval status.\n', + fontWeight: FontWeight.w400, + ), + + ], + ), + buildRichText([ + createTextSpan( + 'For more information please visit ', + color:tColor, + fontSize: 16, + ), + createTextSpan( + 'www.fcsc.gov.ae ', + color: const Color(0xFF568898), + fontSize: 16, + textDecoration: TextDecoration.underline, + ), + ]), + 10.verticalSpace, + Center( child: fcscBanner,), + 50.verticalSpace, + ], + ), + ), + ), + + ), + ); + } +} + +//Question and Answer +class QuestionAnswerScrollView extends StatelessWidget { + QuestionAnswerScrollView({super.key}); + + final List> questionsAndAnswers = [ + {'question': '1. How to Create an Account', 'answer': 'Learn how to register for an account on the FCSC App in a few simple steps.'}, + {'question': '2. Exploring the FCSC Dashboard', 'answer': 'Get a detailed guide on the main sections of the home page, including dashboard features.'}, + {'question': '3. What to Do If Your Registration is Pending Approval', 'answer': 'Understand the approval process and how to check if your registration has been approved by the admin.'}, + {'question':'4. Overview of Key Features in FCSC','answer':'Discover the essential features you can use within the FCSC App to enhance your experience.'} + ]; + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + children: questionsAndAnswers.map((qa) => QuestionAnswerCard(qa: qa)).toList(), + ), + ); + } +} + +class QuestionAnswerCard extends StatefulWidget { + final Map qa; + const QuestionAnswerCard({required this.qa}); + + @override + _QuestionAnswerCardState createState() => _QuestionAnswerCardState(); +} + +class _QuestionAnswerCardState extends State { + bool isExpanded = false; + + @override + Widget build(BuildContext context) { + return Card( + color: Colors.transparent, + elevation: 0, + margin: EdgeInsets.zero, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + dense: true, + textColor: Color(0xFF265E84), + title: Text( + widget.qa['question']!, + style: TextStyle(fontWeight: FontWeight.w600, fontSize: 15), + ), + trailing: Icon(isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down), + onTap: () { + setState(() { + isExpanded = !isExpanded; + }); + }, + ), + if (isExpanded) + Padding( + padding: EdgeInsets.only(bottom: 2), + child: Text( + widget.qa['answer']!, + style: TextStyle(color: Colors.black54), + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/textRich.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/textRich.dart new file mode 100644 index 00000000..aefcc5d2 --- /dev/null +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/textRich.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; + +class ExpandableRichText extends StatefulWidget { + final List textSpans; + final int maxLines; + final TextStyle? defaultStyle; + + ExpandableRichText({ + required this.textSpans, + this.maxLines = 0, + this.defaultStyle, + }); + + @override + _ExpandableRichTextState createState() => _ExpandableRichTextState(); +} + +class _ExpandableRichTextState extends State { + bool isExpanded = false; + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, constraints) { + final span = TextSpan( + children: widget.textSpans, + style: widget.defaultStyle, + ); + + final textPainter = TextPainter( + text: span, + maxLines: widget.maxLines, + textDirection: TextDirection.ltr, + ); + + textPainter.layout(maxWidth: constraints.maxWidth); + + final isOverflowing = textPainter.didExceedMaxLines; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text.rich( + span, + maxLines: isExpanded ? null : widget.maxLines, + overflow: isExpanded ? null : TextOverflow.ellipsis, + ), + if (isOverflowing) + GestureDetector( + onTap: () { + setState(() { + isExpanded = !isExpanded; + }); + }, + child: Text( + isExpanded ? 'View less' : 'View more', + style: TextStyle( + + color: Color(0xFF265E84), + decoration: TextDecoration.underline, + decorationColor: Color(0xFF265E84), + + ), + ), + ), + ], + ); + }, + ); + } +} + +/// Helper method to build `Text.rich` +Widget buildRichText(List textSpans) { + return Text.rich( + TextSpan(children: textSpans), + textAlign: TextAlign.left, + ); +} + +/// Helper method to create custom `TextSpan` +TextSpan createTextSpan( + String text, { + double? fontSize, + Color color = const Color(0xFF898C81), + FontWeight fontWeight = FontWeight.w500, + double? height, + double defaultFontSize = 14, + TextDecoration textDecoration = TextDecoration.none, + Color? decorationColor, + double spacingTop = 0.0, // Custom top spacing + double spacingBottom = 0.0, + }) { + String spacedText = '${'\n' * spacingTop.toInt()}$text${'\n' * spacingBottom.toInt()}'; + + return TextSpan( + text: spacedText, + style: TextStyle( + fontSize: fontSize ?? defaultFontSize, + color: color, + fontWeight: fontWeight, + height: height, + decoration: textDecoration, + decorationColor: decorationColor ?? color, + ), + ); + +} + + diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/user_guide.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/user_guide.dart new file mode 100644 index 00000000..cd9ed57a --- /dev/null +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/user_guide.dart @@ -0,0 +1,168 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; +class UserGuide extends StatefulWidget { + const UserGuide({super.key}); + + @override + State createState() => _UserGuideState(); +} + +class _UserGuideState extends State { + @override + Widget build(BuildContext context) { + + List createRows(List>> items) { + return items.map((pair) { + return Padding( + padding: const EdgeInsets.only(bottom: 20), // Add space between rows + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: pair.map((item) { + return userGuides( + color: item['color'] as Color, + text: item['text'] as String, + dynamicIcon: item['icon'], + no: item['index'] as String, + routePath:item['routePath']as String, + ); + }).toList(), + ), + ); + }).toList(); + } + + return BaseScaffold( + title: Text('User Guide'), + body: SingleChildScrollView( + child: Container( + color: Colors.grey[300], // Grey background for content + padding: const EdgeInsets.all(16.0), // Padding around content + child: Column( + children: createRows([ + // Each pair defines a row of (Color, Text) pairs + [ + {'routePath':'features','color': Color(0xFF90B0D5), 'text': 'Getting Started', 'icon': 'START', 'index': '1'}, + {'routePath':'features','color': Color(0xFF497B8C), 'text': 'Account & Profile', 'icon': Icons.person_outline_rounded, 'index': '2'}, + ], + [ + {'routePath':'features','color': Color(0xFFAA8E83), 'text': 'Using Features', 'icon': Icons.stars_outlined, 'index': '3'}, + {'routePath':'features','color': Color(0xFF265E84), 'text': 'Troubleshooting', 'icon': Icons.troubleshoot_outlined, 'index': '4'}, + ], + [ + {'routePath':'features','color': Color(0xFF7296BE), 'text': 'FAQs', 'icon': Icons.question_answer_sharp, 'index': '5'}, + {'routePath':'features','color': Color(0xFF7DAFBC), 'text': 'Advanced Settings', 'icon': Icons.settings_outlined, 'index': '6'}, + ], + ]), + ), + ), + ), ); + } +} + +class userGuides extends StatelessWidget { + + const userGuides({super.key, required this.routePath ,required this.color, required this.text,required this.dynamicIcon,required this.no}); + final Color color; + final String text; + final dynamic dynamicIcon; + final String no; + final String routePath; + + + Widget buildDynamicWidget(dynamic icons) { + if (dynamicIcon is IconData) { + + return Icon( + icons, + size: 38, + color: Colors.white, + ); + } else if (dynamicIcon is String) { + // Create a Text widget if variable is a String + return Text( + icons, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 20, + color: Colors.white, + ), + ); + } else { + // Handle unsupported types + return Text( + 'Unsupported type', + style: TextStyle(color: Colors.red), + ); + } + } + + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: (){ + context.push('/user-guide/$routePath'); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + height: 115, + width: 148, + margin: EdgeInsets.all(1), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(10), + ), + alignment: Alignment.center, + child: Stack( + children: [Column( + mainAxisAlignment: MainAxisAlignment.center, // Align icon and text in the center + children: [ + // Icon( + // size:38, + // icons, // Home icon + // color: Colors.white, + // ), + buildDynamicWidget(dynamicIcon), + + SizedBox(width: 10,height: 15,), // Space between icon and text + Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 4, vertical: 4), // Padding inside the text background + decoration: BoxDecoration( + color: Colors.white, // Background color for text + borderRadius: BorderRadius.circular(5), // Rounded corners for text background + ), + child: Text( + text, + style: TextStyle( + color: color, // Text color + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ), + ], + ), + Positioned( + top: 6, // Distance from the top of the container + left: 6, // Distance from the left of the container + child: Container( + padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), + color: Colors.transparent, // Background color for the number + child: Text( + no, + style: TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + ),], + ) + ), + ); + } +} + diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index ba1d5bd7..1e220431 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -25,7 +25,7 @@ class BaseScaffold extends StatelessWidget { return Scaffold( appBar: AppBar(title: title, actions: [ IconButton(onPressed: () {}, icon: Icon(Icons.toggle_off_outlined)), - ]), + ],), drawer: Drawer( child: ListView( children: [ @@ -39,19 +39,19 @@ class BaseScaffold extends StatelessWidget { SizedBox( width: mywidth / 8, child: Image( - image: AssetImage('assets/logos/fcsc.png'))), + image: AssetImage('assets/logos/fcsc.png'),),), ], ), Divider(), InkWell( - onTap: () => context.go('/editProfile'), + onTap: () => context.go('/profile'), child: Row( children: [ SizedBox( width: mywidth / 8, child: Image( image: AssetImage( - 'assets/edit_profile/profile.png'))), + 'assets/edit_profile/profile.png',),),), SizedBox( width: mywidth / 20, ), @@ -59,12 +59,12 @@ class BaseScaffold extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Mohammad'), - Text('Mohammad@fcsc.com') + Text('Mohammad@fcsc.com'), ], - ) + ), ], ), - ) + ), ], ), ), @@ -73,10 +73,20 @@ class BaseScaffold extends StatelessWidget { height: myheight / 15, width: mywidth / 15, child: Image( - image: AssetImage('assets/icons/drawer/message.png'))), + image: AssetImage('assets/icons/drawer/message.png'),),), title: Text('Feedback'), onTap: () => context.go('/feedback'), ), + //user Guide + ListTile( + leading: SizedBox( + height: myheight / 15, + width: mywidth / 15, + child: Image( + image: AssetImage('assets/icons/drawer/book.png'),),), + title: Text('User Guide'), + onTap: () => context.go('/user-guide'), + ), ListTile( leading: SizedBox( height: myheight / 15, From 5be9097964463406ac79b7ccb30d9ea3cb3ce8b1 Mon Sep 17 00:00:00 2001 From: VINISTAN Date: Thu, 19 Dec 2024 15:16:51 +0530 Subject: [PATCH 3/4] routing fix --- lib/config/my_router.dart | 9 +- .../routes/auth_routes/login_route.dart | 126 ++++++++++-------- 2 files changed, 78 insertions(+), 57 deletions(-) diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index cdfe3b13..5b056bc0 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -311,8 +311,13 @@ final GoRouter router = GoRouter( routes: [ GoRoute( path: '/', -//builder: (context, state) => LoginRoute(), - builder: (context, state) => MyHomePage(), +builder: (context, state) => LoginRoute(), + //builder: (context, state) => MyHomePage(), + ), + GoRoute( + path: '/login', + builder: (context, state) => LoginRoute(), + ), GoRoute( path: '/myhomepage', diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index cbf28f0a..0359ab44 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -515,8 +515,14 @@ class _LoginRouteState extends State { bool _obscurePassword = true; @override Widget build(BuildContext context) { - double screenheight = MediaQuery.of(context).size.height; - double screenwidth = MediaQuery.of(context).size.width; + double screenheight = MediaQuery + .of(context) + .size + .height; + double screenwidth = MediaQuery + .of(context) + .size + .width; return Scaffold( body: Padding( padding: const EdgeInsets.all(20.0), @@ -533,20 +539,20 @@ class _LoginRouteState extends State { fontSize: 32, fontWeight: FontWeight.w400), ), SizedBox(height: 5), - Text('Please login to access',style: TextStyle( + Text('Please login to access', style: TextStyle( fontFamily: context.translate( 'Roboto', 'NotoKufi', ), color: Color(0xFF898C81), fontSize: 18, fontWeight: FontWeight.bold),), - Text("UAE's key official statistics",style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF898C81), - fontSize: 16, fontWeight: FontWeight.bold),), + Text("UAE's key official statistics", style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Color(0xFF898C81), + fontSize: 16, fontWeight: FontWeight.bold),), SizedBox(height: 10), // Display this if registration is pending approval @@ -556,16 +562,20 @@ class _LoginRouteState extends State { decoration: InputDecoration( hintText: "Username", //hintText: _showHints[0] ? 'Username' : null, - prefixIcon: Image.asset("assets/icons/misc/person.png",scale: 2,color: Colors.lightBlueAccent,), - border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)), + prefixIcon: Image.asset( + "assets/icons/misc/person.png", scale: 2, + color: Colors.lightBlueAccent,), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15)), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide(color: Colors.blue.shade900,) + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide(color: Colors.blue.shade900,) ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), // Keep rounded corners + borderRadius: BorderRadius.circular(10), + // Keep rounded corners borderSide: BorderSide( - color: Colors.blue,// Default border color + color: Colors.blue, // Default border color width: 1.0, // Border width when not focused ), ), @@ -583,8 +593,10 @@ class _LoginRouteState extends State { // obscureText: _obscurePassword, decoration: InputDecoration( hintText: "Password", - // hintText: _showHints[2] ? 'Enter your password' : null, - prefixIcon: Image.asset("assets/icons/misc/lock.png",scale: 2,color: Colors.lightBlueAccent,), + // hintText: _showHints[2] ? 'Enter your password' : null, + prefixIcon: Image.asset( + "assets/icons/misc/lock.png", scale: 2, + color: Colors.lightBlueAccent,), suffixIcon: IconButton( icon: Icon( _obscurePassword @@ -598,16 +610,18 @@ class _LoginRouteState extends State { }); }, ), - border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(15)), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide(color: Colors.blue.shade900,), + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide(color: Colors.blue.shade900,), ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), // Keep rounded corners + borderRadius: BorderRadius.circular(10), + // Keep rounded corners borderSide: BorderSide( - color: Colors.blue,// Default border color + color: Colors.blue, // Default border color width: 1.0, // Border width when not focused ), ), @@ -620,14 +634,16 @@ class _LoginRouteState extends State { SizedBox(height: 10), Row(mainAxisAlignment: MainAxisAlignment.end, - children: [Text("Forgot Password?", - style: TextStyle(color: Color(0xFF985400),fontWeight: FontWeight.bold - ),)],), + children: [Text("Forgot Password?", + style: TextStyle( + color: Color(0xFF985400), fontWeight: FontWeight.bold + ),) + ],), SizedBox(height: 20), SizedBox( width: screenwidth, child: ElevatedButton( - onPressed: (){ + onPressed: () { context.go('/profile'); }, //_registerUser, @@ -648,33 +664,33 @@ class _LoginRouteState extends State { ), SizedBox(width: 8), Icon(Icons.arrow_forward_ios, - color: Colors.white, + color: Colors.white, size: 10, ), ], ), ), ), - SizedBox(height: screenheight/20), + SizedBox(height: screenheight / 20), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( - "Don't have an account? ", - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF898C81), - fontSize: 18, fontWeight: FontWeight.bold), - ), - InkWell( - onTap: (){ - context.go('/registration'); - }, - child: Text( - " Register Now", + Text( + "Don't have an account? ", + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + color: Color(0xFF898C81), + fontSize: 18, fontWeight: FontWeight.bold), + ), + InkWell( + onTap: () { + context.go('/registration'); + }, + child: Text( + " Register Now", style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -682,12 +698,12 @@ class _LoginRouteState extends State { ), color: Color(0xFF985400), fontSize: 18, fontWeight: FontWeight.bold), + ), ), - ), - ],), + ],), SizedBox( - height: screenheight/20, + height: screenheight / 20, ), SizedBox( width: screenwidth, @@ -714,13 +730,13 @@ class _LoginRouteState extends State { ), SizedBox(width: 8), Icon(Icons.arrow_forward_ios, - color: Colors.white,size: 10,), + color: Colors.white, size: 10,), ], ), ), ), SizedBox( - height: screenheight/15, + height: screenheight / 15, ), Center( child: Container( @@ -729,7 +745,8 @@ class _LoginRouteState extends State { decoration: BoxDecoration( image: DecorationImage( image: AssetImage( - "assets/splash_screen/logo.png"), // Background image asset + "assets/splash_screen/logo.png"), + // Background image asset fit: BoxFit.fill, ), ), @@ -740,8 +757,8 @@ class _LoginRouteState extends State { ), ), ); -<<<<<<< HEAD -======= + + final form = Form( key: formKey, child: Column( @@ -940,6 +957,5 @@ class _LoginRouteState extends State { body: SafeArea(child: scaffoldBody), ); return bgScaffold; ->>>>>>> b0c5ebce3deb7da2aa24b0ea5ffe684df7dfb7bf } -} + From 8b3f46b29446cdbae14e0f16bc0c0f8bd43b0463 Mon Sep 17 00:00:00 2001 From: VINISTAN Date: Thu, 19 Dec 2024 19:04:37 +0530 Subject: [PATCH 4/4] login router --- .../routes/auth_routes/login_route.dart | 1049 +++++------------ 1 file changed, 313 insertions(+), 736 deletions(-) diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index 0359ab44..7e56df9f 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -1,10 +1,9 @@ -import 'package:excel/excel.dart'; import 'package:external_repos/external_repos.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:the_validator/the_validator.dart'; import 'package:uae_stat/config/my_theme.dart'; import 'package:uae_stat/domain/use_cases/auth_use_case.dart'; @@ -19,746 +18,329 @@ import 'package:uae_stat/presentation/components/space.dart'; import 'package:uae_stat/presentation/components/themed_text_field.dart'; import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; -import '../../Screens/profilepage.dart'; import '../../Screens/auth_verification/registration.dart'; import 'package:pocketbase/pocketbase.dart'; -// class LoginRoute extends HookConsumerWidget { -// final pb = PocketBase('https://pb.venbait.in'); -// // final _pb = PocketBase('http://127.0.0.1:8090'); -// LoginRoute({super.key}); -// -// static final formKey = GlobalKey(); -// -// Future profileStatus(String userId) async { -// try { -// // Authenticate admin -// final adminAuth = await pb.admins.authWithPassword( -// 'pb@venbainfotech.com', -// 'pb@venbainfotech.com', -// ); -// final String adminToken = adminAuth.token; -// print('adminToken: $adminToken'); -// -// // Fetch user details -// final userDetailsResponse = await pb.collection('users').getOne( -// userId, -// headers: { -// 'Authorization': 'Bearer $adminToken', -// }, -// ); -// print('userDetailsLogin: $userDetailsResponse'); -// -// // Check if 'is_profile_completed' is true or false -// if (userDetailsResponse != null && -// userDetailsResponse.data['is_profile_completed'] != null) { -// return userDetailsResponse.data['is_profile_completed']; -// } else { -// return false; // Default to false if the field is missing or response is null -// } -// } catch (e) { -// print('Error fetching user details: $e'); -// return false; // Return false on error -// } -// } -// -// @override -// Widget build(BuildContext context, WidgetRef ref) { -// final emailCtl = useTextEditingController(); -// final pwCtl = useTextEditingController(); -// final forgotPwBtn = TextButton( -// onPressed: () async { -// final forgotPwFormKey = GlobalKey(); -// final email = await showDialog( -// context: context, -// builder: (dialogCtx) => AlertDialog( -// title: Text( -// context.translate( -// 'Reset Password', -// 'إعادة تعيين كلمة المرور', -// ), -// ), -// 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 (!context.mounted) return; -// await context.loaderWithErrorDialog( -// () => ref -// .read( -// authUseCaseProvider.notifier, -// ) -// .requestPwReset(email), -// ); -// if (!context.mounted) return; -// context.simpleDialog( -// title: context.translate( -// 'Success!', -// 'نجاح', -// ), -// content: context.translate( -// 'An email has been sent to $email with further details.', -// 'تم إرسال بريد إلكتروني إلى $email يتضمن المزيد من التفاصيل.', -// ), -// ); -// }, -// child: Text( -// context.translate( -// 'Forgot Password?', -// 'هل نسيت كلمة السر؟', -// ), -// style: TextStyle( -// fontFamily: context.translate( -// 'Roboto', -// 'NotoKufi', -// ), -// fontWeight: FontWeight.bold, -// fontSize: 14, -// color: MyTheme.topicColor(IndicatorTopic.economy).shade600, -// ), -// ), -// ); -// final loginBtn = SizedBox( -// width: double.infinity, -// child: ElevatedButton( -// onPressed: () { -// context.go('/profile'); -// }, -// // async { -// // final isValid = formKey.currentState!.validate(); -// // if (!isValid) return; -// // final session = await context.loaderWithErrorDialog( -// // () => ref -// // .read( -// // authUseCaseProvider.notifier, -// // ) -// // .login( -// // emailCtl.text, -// // pwCtl.text, -// // ), -// // errorDialogBuilder: ( -// // error, [ -// // StackTrace? stackTrace, -// // ]) { -// // if (error == LoginError.invalidEmailPw) { -// // return context.simpleDialog( -// // title: context.translate( -// // 'Incorrect credentials', -// // 'أوراق غير صحيحة', -// // ), -// // content: context.translate( -// // 'Your email or password is invalid. Please try again.', -// // 'بريدك الإلكتروني أو كلمة المرور غير صالحة. حاول مرة اخرى.', -// // ), -// // ); -// // } -// // if (error == LoginError.emailAddressNotVerified) { -// // return context.simpleDialog( -// // title: context.translate( -// // 'Verification Error', -// // 'خطأ التحقق', -// // ), -// // content: context.translate( -// // '${emailCtl.text} is not a verified email address. Please check your email for a verification link.', -// // '${emailCtl.text} ليس عنوان بريد إلكتروني تم التحقق منه. يرجى التحقق من بريدك الإلكتروني للحصول على رابط التحقق.', -// // ), -// // extraAction: ElevatedButton( -// // onPressed: () { -// // context.go('/profile'); -// // }, -// // // async { -// // // Navigator.of( -// // // context, -// // // rootNavigator: true, -// // // ).pop(); -// // // await context.loaderWithErrorDialog( -// // // () => ref -// // // .read(authUseCaseProvider.notifier) -// // // .requestVerificationEmail(emailCtl.text), -// // // ); -// // // if (!context.mounted) return; -// // // context.simpleDialog( -// // // title: 'Email Re-sent', -// // // content: -// // // 'We\'ve sent you the verification email at ${emailCtl.text} again.', -// // // ); -// // // }, -// // child: Text( -// // context.translate( -// // 'I did not receive an email', -// // 'لم أتلق بريدًا إلكترونيًا', -// // ), -// // ), -// // ), -// // ); -// // } -// // return context.simpleDialog(); -// // }, -// // ); -// // // if (!context.mounted || session == null) return; -// // // Extract userId from the session -// // // final userId = session.id; -// // // -// // // final bool isUpdate = await profileStatus(userId); -// // // -// // // print('Is profile completed: $isUpdate'); -// // -// // // if (isUpdate) { -// // // Navigator.pushReplacement( -// // // context, -// // // MaterialPageRoute(builder: (context) => DemoHome()), -// // // ); -// // // } -// // // else { -// // -// // // Navigator.pushReplacement( -// // // context, -// // // MaterialPageRoute( -// // // builder: (context) => ProfileScreen(userId: userId)), -// // // ); -// // //} -// // -// // // context.go('/${context.language}/${BottomNavBarItem.home.routePath}'); -// // }, -// style: ButtonStyle( -// shape: WidgetStatePropertyAll( -// RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(10), -// ), -// ), -// padding: const WidgetStatePropertyAll( -// EdgeInsets.symmetric(vertical: 10.5), -// ), -// textStyle: WidgetStatePropertyAll( -// TextStyle( -// fontFamily: context.translate( -// 'Roboto', -// 'NotoKufi', -// ), -// fontSize: 16, -// fontWeight: FontWeight.w600, -// ), -// ), -// backgroundColor: WidgetStatePropertyAll( -// MyTheme.topicColor(IndicatorTopic.social), -// ), -// // surfaceTintColor: MaterialStatePropertyAll( -// // MyTheme.economy[800], -// // ), -// foregroundColor: const WidgetStatePropertyAll( -// Colors.white, -// ), -// ), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.center, -// children: [ -// Text( -// context.translate( -// 'Login', -// 'تسجيل الدخول', -// ), -// ), -// 6.horizontalSpace, -// const Icon(Icons.chevron_right_outlined), -// ], -// ), -// ), -// ); -// final form = Form( -// key: formKey, -// child: Column( -// children: [ -// ThemedFormField( -// hintText: context.translate( -// 'Email', -// 'بريد إلكتروني', -// ), -// validator: FieldValidator.email(), -// imgPath: MiscIconAssetPath.person, -// controller: emailCtl, -// ), -// 15.verticalSpace, -// ThemedFormField( -// validator: (text) { -// if (text!.length < 10) { -// return 'The password must be at least 10 characters'; -// } -// return FieldValidator.password(minLength: 10)(text); -// }, -// hintText: context.translate( -// 'Password', -// 'كلمة المرور', -// ), -// imgPath: MiscIconAssetPath.lock, -// controller: pwCtl, -// isObscurable: true, -// ), -// // 6.verticalSpace, -// Align( -// alignment: AlignmentDirectional.topEnd, -// child: forgotPwBtn, -// ), -// 10.verticalSpace, -// loginBtn, -// ], -// ), -// ); -// final helloAndPleaseLoginTexts = Column( -// children: [ -// Text( -// context.translate( -// 'Hello Again!', -// 'مرحبا مجددا!', -// ), -// style: TextStyle( -// fontFamily: context.translate( -// 'Roboto', -// 'NotoKufi', -// ), -// fontSize: 40, -// fontWeight: FontWeight.w300, -// ), -// ), -// 10.verticalSpace, -// Text( -// context.translate( -// 'Please login to access UAE’s key official statistics', -// 'يرجى تسجيل الدخول للوصول إلى الإحصاءات الرسمية الرئيسية لدولة الإمارات العربية المتحدة', -// ), -// textAlign: TextAlign.center, -// style: TextStyle( -// fontFamily: context.translate( -// 'Roboto', -// 'NotoKufi', -// ), -// fontSize: 18, -// color: const Color(0xff898C81), -// fontWeight: FontWeight.w700, -// ), -// ), -// ], -// ); -// final dontHaveAnAccountRegisterBtn = TextButton( -// onPressed: () => { -// Navigator.push( -// context, -// MaterialPageRoute(builder: (context) => RegisterScreen()), -// ), -// }, -// child: Text.rich( -// textAlign: TextAlign.center, -// TextSpan( -// style: TextStyle( -// fontFamily: context.translate( -// 'Roboto', -// 'NotoKufi', -// ), -// fontSize: 18, -// fontWeight: FontWeight.bold, -// ), -// children: [ -// TextSpan( -// text: context.translate( -// 'Don\'t have an account? ', -// 'ليس لديك حساب؟', -// ), -// style: const TextStyle( -// color: Color(0xff898C81), -// ), -// ), -// const TextSpan( -// text: ' ', -// ), -// TextSpan( -// text: context.translate( -// 'Register Now', -// 'سجل الان', -// ), -// style: TextStyle( -// color: MyTheme.topicColor(IndicatorTopic.economy).shade600, -// ), -// ), -// ], -// ), -// ), -// ); -// final continueAsGuestBtn = SizedBox( -// width: double.infinity, -// child: ElevatedButton( -// onPressed: () => context -// .go('/${context.language}/${BottomNavBarItem.home.routePath}'), -// style: ButtonStyle( -// shape: WidgetStatePropertyAll( -// RoundedRectangleBorder( -// borderRadius: BorderRadius.circular(10), -// ), -// ), -// padding: const WidgetStatePropertyAll( -// EdgeInsets.symmetric(vertical: 10.5), -// ), -// textStyle: WidgetStatePropertyAll( -// TextStyle( -// fontFamily: context.translate( -// 'Roboto', -// 'NotoKufi', -// ), -// fontSize: 16, -// fontWeight: FontWeight.w600, -// ), -// ), -// backgroundColor: WidgetStatePropertyAll( -// MyTheme.topicColor(IndicatorTopic.environment), -// ), -// foregroundColor: const WidgetStatePropertyAll( -// Colors.white, -// ), -// ), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.center, -// children: [ -// Text( -// context.translate( -// 'Continue as Guest', -// 'استمر كضيف', -// ), -// ), -// 6.horizontalSpace, -// const Icon(Icons.chevron_right_outlined), -// ], -// ), -// ), -// ); -// final fcscBanner = Image.asset( -// BannerAssetPath.fcsc, -// height: 56, -// ); -// final screenWidth = MediaQuery.of(context).size.width; -// final listViewHorizontalPadding = -// screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2; -// final scaffoldBody = ListView( -// padding: EdgeInsets.symmetric( -// horizontal: listViewHorizontalPadding.toDouble(), -// ), -// children: [ -// 36.verticalSpace, -// const Align( -// alignment: AlignmentDirectional.topEnd, -// child: LangToggle(), -// ), -// 16.verticalSpace, -// helloAndPleaseLoginTexts, -// 42.verticalSpace, -// form, -// 20.verticalSpace, -// dontHaveAnAccountRegisterBtn, -// 36.verticalSpace, -// continueAsGuestBtn, -// 72.verticalSpace, -// fcscBanner, -// ], -// ); -// final bgScaffold = Scaffold( -// backgroundColor: Colors.white, -// body: SafeArea(child: scaffoldBody), -// ); -// return bgScaffold; -// } -// } +class LoginRoute extends HookConsumerWidget { + final pb = PocketBase('https://pb.venbait.in'); + // final _pb = PocketBase('http://127.0.0.1:8090'); + LoginRoute({super.key}); + dynamic userData; + String? role; -class LoginRoute extends StatefulWidget { - const LoginRoute({super.key}); + static final formKey = GlobalKey(); + + Future profileStatus(String userId) async { + try { + // Authenticate admin + final adminAuth = await pb.admins.authWithPassword( + 'pb@venbainfotech.com', + 'pb@venbainfotech.com', + ); + final String adminToken = adminAuth.token; + print('adminToken: $adminToken'); + + // Fetch user details + final userDetailsResponse = await pb.collection('users').getOne( + userId, + headers: { + 'Authorization': 'Bearer $adminToken', + }, + ); + + print('userDetailsLogin: $userDetailsResponse'); + + // Check if user is verified + role = userDetailsResponse.data['role']; + final bool? isVerified = userDetailsResponse.data['verified']; + final bool? isUserMailVerified = + userDetailsResponse.data['user_mail_verify']; + + // Check admin and email verification statuses + if (isVerified == false) { + throw Exception('Admin not approved'); + } + if (isUserMailVerified == false) { + throw Exception('Email not verified'); + } + userData = userDetailsResponse; + // Check if 'is_profile_completed' is true + final bool isProfileCompleted = + userDetailsResponse.data['is_profile_completed'] ?? false; + + return isProfileCompleted; + } catch (e) { + print('Error fetching user details: $e'); + rethrow; + } + } + + Future saveUserId(String userId) async { + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('userId', userId); // Save userId locally + } @override - State createState() => _LoginRouteState(); -} - -class _LoginRouteState extends State { - final _formKey = GlobalKey(); - bool _obscurePassword = true; - @override - Widget build(BuildContext context) { - double screenheight = MediaQuery - .of(context) - .size - .height; - double screenwidth = MediaQuery - .of(context) - .size - .width; - return Scaffold( - body: Padding( - padding: const EdgeInsets.all(20.0), - child: Form( - key: _formKey, - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: screenheight / 6), - Text( - 'Hello Again !', - style: TextStyle( - fontSize: 32, fontWeight: FontWeight.w400), - ), - SizedBox(height: 5), - Text('Please login to access', style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF898C81), - fontSize: 18, fontWeight: FontWeight.bold),), - Text("UAE's key official statistics", style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF898C81), - fontSize: 16, fontWeight: FontWeight.bold),), - - SizedBox(height: 10), - // Display this if registration is pending approval - TextFormField( - // controller: _usernameController, - // focusNode: _focusNodes[0], - decoration: InputDecoration( - hintText: "Username", - //hintText: _showHints[0] ? 'Username' : null, - prefixIcon: Image.asset( - "assets/icons/misc/person.png", scale: 2, - color: Colors.lightBlueAccent,), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(15)), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide(color: Colors.blue.shade900,) - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - // Keep rounded corners - borderSide: BorderSide( - color: Colors.blue, // Default border color - width: 1.0, // Border width when not focused - ), - ), - counterText: '', - ), - //validator: _validateUsername, - maxLength: - 40, // Set the maximum length to 20 characters - //maxLengthEnforcement: MaxLengthEnforcement.enforced, - ), - SizedBox(height: 20), - TextFormField( - // controller: _passwordController, - // focusNode: _focusNodes[2], - // obscureText: _obscurePassword, - decoration: InputDecoration( - hintText: "Password", - // hintText: _showHints[2] ? 'Enter your password' : null, - prefixIcon: Image.asset( - "assets/icons/misc/lock.png", scale: 2, - color: Colors.lightBlueAccent,), - suffixIcon: IconButton( - icon: Icon( - _obscurePassword - ? Icons.visibility - : Icons.visibility_off, - color: Colors.grey, - ), - onPressed: () { - setState(() { - _obscurePassword = !_obscurePassword; - }); - }, - ), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(15)), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide(color: Colors.blue.shade900,), - - ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - // Keep rounded corners - borderSide: BorderSide( - color: Colors.blue, // Default border color - width: 1.0, // Border width when not focused - ), - ), - counterText: '', - ), - //validator: _validatePassword, - maxLength: 40, - maxLengthEnforcement: MaxLengthEnforcement.enforced, - ), - - SizedBox(height: 10), - Row(mainAxisAlignment: MainAxisAlignment.end, - children: [Text("Forgot Password?", - style: TextStyle( - color: Color(0xFF985400), fontWeight: FontWeight.bold - ),) - ],), - SizedBox(height: 20), - SizedBox( - width: screenwidth, - child: ElevatedButton( - onPressed: () { - context.go('/profile'); - }, - //_registerUser, - style: ElevatedButton.styleFrom( - backgroundColor: Color( - 0xFFA7887A), // Brownish color for Register - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Login", - style: TextStyle( - fontSize: 16, color: Colors.white), - ), - SizedBox(width: 8), - Icon(Icons.arrow_forward_ios, - color: Colors.white, - size: 10, - ), - ], - ), - ), - ), - SizedBox(height: screenheight / 20), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Don't have an account? ", - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF898C81), - fontSize: 18, fontWeight: FontWeight.bold), - ), - InkWell( - onTap: () { - context.go('/registration'); - }, - child: Text( - " Register Now", - style: TextStyle( - fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - ), - color: Color(0xFF985400), - fontSize: 18, fontWeight: FontWeight.bold), - ), - ), - ],), - - SizedBox( - height: screenheight / 20, - ), - SizedBox( - width: screenwidth, - child: ElevatedButton( - onPressed: () { - context.go('/myhomepage'); - }, - style: ElevatedButton.styleFrom( - backgroundColor: Color( - 0xFF82AFCB), // Blueish color for Login - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Continue as guest", - style: TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - SizedBox(width: 8), - Icon(Icons.arrow_forward_ios, - color: Colors.white, size: 10,), - ], - ), - ), - ), - SizedBox( - height: screenheight / 15, - ), - Center( - child: Container( - height: screenheight / 13, - width: screenwidth / 3, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "assets/splash_screen/logo.png"), - // Background image asset - fit: BoxFit.fill, - ), - ), - )) - ], + Widget build(BuildContext context, WidgetRef ref) { + final emailCtl = useTextEditingController(); + final pwCtl = useTextEditingController(); + final forgotPwBtn = TextButton( + onPressed: () async { + final forgotPwFormKey = GlobalKey(); + final email = await showDialog( + context: context, + builder: (dialogCtx) => AlertDialog( + title: Text( + context.translate( + 'Reset Password', + 'إعادة تعيين كلمة المرور', + ), ), + 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 (!context.mounted) return; + await context.loaderWithErrorDialog( + () => ref + .read( + authUseCaseProvider.notifier, + ) + .requestPwReset(email), + ); + if (!context.mounted) return; + context.simpleDialog( + title: context.translate( + 'Success!', + 'نجاح', + ), + content: context.translate( + 'An email has been sent to $email with further details.', + 'تم إرسال بريد إلكتروني إلى $email يتضمن المزيد من التفاصيل.', + ), + ); + }, + child: Text( + context.translate( + 'Forgot Password?', + 'هل نسيت كلمة السر؟', + ), + style: TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontWeight: FontWeight.bold, + fontSize: 14, + color: MyTheme.topicColor(IndicatorTopic.economy).shade600, ), ), ); + final loginBtn = SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () async { + final isValid = formKey.currentState!.validate(); + if (!isValid) return; + final session = await context.loaderWithErrorDialog( + () => ref + .read( + authUseCaseProvider.notifier, + ) + .login( + emailCtl.text, + pwCtl.text, + ), + errorDialogBuilder: ( + error, [ + StackTrace? stackTrace, + ]) { + if (error == LoginError.invalidEmailPw) { + return context.simpleDialog( + title: context.translate( + 'Incorrect credentials', + 'أوراق غير صحيحة', + ), + content: context.translate( + 'Your email or password is invalid. Please try again.', + 'بريدك الإلكتروني أو كلمة المرور غير صالحة. حاول مرة اخرى.', + ), + ); + } + // if (error == LoginError.emailAddressNotVerified) { + // return context.simpleDialog( + // title: context.translate( + // 'Verification Error', + // 'خطأ التحقق', + // ), + // content: context.translate( + // '${emailCtl.text} is not a verified email address. Please check your email for a verification link.', + // '${emailCtl.text} ليس عنوان بريد إلكتروني تم التحقق منه. يرجى التحقق من بريدك الإلكتروني للحصول على رابط التحقق.', + // ), + // extraAction: ElevatedButton( + // onPressed: () async { + // Navigator.of( + // context, + // rootNavigator: true, + // ).pop(); + // await context.loaderWithErrorDialog( + // () => ref + // .read(authUseCaseProvider.notifier) + // .requestVerificationEmail(emailCtl.text), + // ); + // if (!context.mounted) return; + // context.simpleDialog( + // title: 'Email Re-sent', + // content: + // 'We\'ve sent you the verification email at ${emailCtl.text} again.', + // ); + // }, + // child: Text( + // context.translate( + // 'I did not receive an email', + // 'لم أتلق بريدًا إلكترونيًا', + // ), + // ), + // ), + // ); + // } + return context.simpleDialog(); + }, + ); + if (!context.mounted || session == null) return; + final userId = session.id; + if (userId.isNotEmpty) { + await saveUserId(userId); + } + try { + final bool isProfileComplete = await profileStatus(userId); + print(isProfileComplete); + if (isProfileComplete) { + print('home'); + if (role == 'admin') { + context.go('/manageuser'); + } else { + context.go('/myhomepage'); + } + // context.go('/myhomepage'); + } else { + print('profile'); + if (userId != null && userId.isNotEmpty) { + context.go('/profile/$userId'); + } else { + print('Error: userId is null or empty.'); + } + } + } catch (e) { + // Handle specific errors based on their message + if (e.toString().contains('Admin not approved')) { + context.simpleDialog( + title: context.translate( + 'Admin Approval Required', 'موافقة المسؤول مطلوبة'), + content: context.translate( + 'Your account has not been approved by the admin.', + 'لم تتم الموافقة على حسابك من قبل المسؤول.', + ), + ); + } else if (e.toString().contains('Email not verified')) { + context.simpleDialog( + title: context.translate( + 'Email Not Verified', 'البريد الإلكتروني غير مُحقق'), + content: context.translate( + 'Your email address is not verified. Please check your email.', + 'عنوان بريدك الإلكتروني غير مُحقق. يرجى التحقق من بريدك الإلكتروني.', + ), + ); + } else { + print('Unexpected error: $e'); + } + } + // context.go('/${context.language}/${BottomNavBarItem.home.routePath}'); + }, + style: ButtonStyle( + shape: WidgetStatePropertyAll( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + padding: const WidgetStatePropertyAll( + EdgeInsets.symmetric(vertical: 10.5), + ), + textStyle: WidgetStatePropertyAll( + TextStyle( + fontFamily: context.translate( + 'Roboto', + 'NotoKufi', + ), + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + backgroundColor: WidgetStatePropertyAll( + MyTheme.topicColor(IndicatorTopic.social), + ), + // surfaceTintColor: MaterialStatePropertyAll( + // MyTheme.economy[800], + // ), + foregroundColor: const WidgetStatePropertyAll( + Colors.white, + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + context.translate( + 'Login', + 'تسجيل الدخول', + ), + ), + 6.horizontalSpace, + const Icon(Icons.chevron_right_outlined), + ], + ), + ), + ); final form = Form( key: formKey, child: Column( @@ -834,12 +416,7 @@ class _LoginRouteState extends State { ], ); final dontHaveAnAccountRegisterBtn = TextButton( - onPressed: () => { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => RegisterScreen()), - ), - }, + onPressed: () => {context.go('/register')}, child: Text.rich( textAlign: TextAlign.center, TextSpan( @@ -958,4 +535,4 @@ class _LoginRouteState extends State { ); return bgScaffold; } - +}