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 5be9097964463406ac79b7ccb30d9ea3cb3ce8b1 Mon Sep 17 00:00:00 2001 From: VINISTAN Date: Thu, 19 Dec 2024 15:16:51 +0530 Subject: [PATCH 2/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 3/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; } - +} From ebb16d6f36b1d0c12db4de9eb9738434a3cae3dd Mon Sep 17 00:00:00 2001 From: venbaittech Date: Thu, 26 Dec 2024 10:58:31 +0530 Subject: [PATCH 4/4] manage user and mail issue fix --- assets/icons/drawer/logout.png | Bin 0 -> 10318 bytes lib/config/my_router.dart | 5 + .../auth_verification/registration.dart | 130 ++++----- lib/presentation/Screens/demo_home.dart | 273 ++++++++++++++++-- lib/presentation/Screens/profilepage.dart | 67 +++-- .../routes/auth_routes/login_route.dart | 12 +- .../tab_routes/home_route.dart | 155 +++++----- .../Drawer Items/edit_profile.dart | 65 +++-- .../Drawer Items/manage_users.dart | 4 +- .../drawer_routes/custom_drawer_routes.dart | 9 + pubspec.lock | 10 +- pubspec.yaml | 1 + 12 files changed, 526 insertions(+), 205 deletions(-) create mode 100644 assets/icons/drawer/logout.png diff --git a/assets/icons/drawer/logout.png b/assets/icons/drawer/logout.png new file mode 100644 index 0000000000000000000000000000000000000000..a0b94ff75722a7f8eb0445e627bba7dabcbe7254 GIT binary patch literal 10318 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 RegisterScreen(), ), + GoRoute( + path: '/DemoHome', + builder: (context, state) => ChartPage(), + ), 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 d83f2db4..0ec33c48 100644 --- a/lib/presentation/Screens/auth_verification/registration.dart +++ b/lib/presentation/Screens/auth_verification/registration.dart @@ -233,30 +233,6 @@ class _RegisterScreenState extends State { if (_formKey.currentState?.validate() ?? false) { if (isChecked) { try { - final existingUsers = await pb.collection('users').getList( - filter: 'email="${_emailController.text}"', - ); - - if (existingUsers.items.isNotEmpty) { - // Email already exists - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text('Email Exists'), - content: Text( - 'Email ID already exists. Please use a different email.'), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text('OK'), - ), - ], - ); - }, - ); - return; // Stop registration process - } final adminAuth = await pb.admins .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); @@ -287,10 +263,33 @@ class _RegisterScreenState extends State { throw Exception('User registration failed: missing user ID'); } } catch (e) { - setState(() { - registrationFailed = true; - registrationSuccess = false; - }); + // Check if the error is due to an invalid or already used email + if (e + .toString() + .contains('The email is invalid or already in use.')) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Email Exists'), + content: Text( + 'Email ID already exists. Please use a different email.'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text('OK'), + ), + ], + ); + }, + ); + } else { + // Handle other types of errors + setState(() { + registrationFailed = true; + registrationSuccess = false; + }); + } } } else { setState(() { @@ -452,7 +451,7 @@ class _RegisterScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox(height: screenheight / 6), + SizedBox(height: screenheight / 15), Text( 'Register', style: TextStyle( @@ -662,7 +661,7 @@ class _RegisterScreenState extends State { width: screenwidth / 1.3, child: ElevatedButton( onPressed: () { - // Add your login logic here + context.go('/'); }, style: ElevatedButton.styleFrom( backgroundColor: Color( @@ -671,44 +670,41 @@ class _RegisterScreenState extends State { borderRadius: BorderRadius.circular(10), ), ), - // child: Row( - // mainAxisSize: MainAxisSize.min, - // children: [ - // Text( - // "Login", - // style: TextStyle( - // fontSize: 16, color: Colors.white - // ), - // - // - // ), - // SizedBox(width: 8), - // Icon(Icons.arrow_forward, - // color: Colors.white), - // ], - // ), - - child: GestureDetector( - onTap: () { - // Navigate to LoginRoute - context.go('/'); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Login", - style: TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - SizedBox(width: 8), - Icon(Icons.arrow_forward, - color: Colors.white), - ], - ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Login", + style: TextStyle( + fontSize: 16, color: Colors.white), + ), + SizedBox(width: 8), + Icon(Icons.arrow_forward, + color: Colors.white), + ], ), + + // child: GestureDetector( + // onTap: () { + // // Navigate to LoginRoute + // context.go('/'); + // }, + // child: Row( + // mainAxisSize: MainAxisSize.min, + // children: [ + // Text( + // "Login", + // style: TextStyle( + // fontSize: 16, + // color: Colors.white, + // ), + // ), + // SizedBox(width: 8), + // Icon(Icons.arrow_forward, + // color: Colors.white), + // ], + // ), + // ), ), ), SizedBox( diff --git a/lib/presentation/Screens/demo_home.dart b/lib/presentation/Screens/demo_home.dart index 402bc535..225f1b1b 100644 --- a/lib/presentation/Screens/demo_home.dart +++ b/lib/presentation/Screens/demo_home.dart @@ -1,29 +1,262 @@ +import 'dart:convert'; import 'package:flutter/material.dart'; -import 'dart:async'; +import 'package:go_router/go_router.dart'; +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; // Import Syncfusion charts package +import 'package:http/http.dart' as http; -import 'package:uae_stat/domain/use_cases/language.dart'; - -import '../components/my_drawer.dart'; - -class DemoHome extends StatefulWidget { - @override - State createState() => _DemoHomeState(); +void main() { + runApp(MyApp()); } -class _DemoHomeState extends State { +class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - drawer: const MyDrawer(), - appBar: AppBar( - backgroundColor: const Color(0xFFf8f9ff), - title: Text(context.translate('Home', 'نموذج الملاحظات')), - ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Center( - child: Text('Home Page'), - )), + return MaterialApp( + home: ChartPage(), ); } } + +class ChartPage extends StatefulWidget { + @override + ChartPageState createState() => ChartPageState(); +} + +class ChartPageState extends State { + List chartsData = []; + bool isLoading = true; + + @override + void initState() { + super.initState(); + fetchChartData(); + } + + Future fetchChartData() async { + const baseUrl = + 'https://pb.venbait.in/api/custom/apicall'; // Replace with your server URL + final url = Uri.parse('$baseUrl?dataset=hotels'); + + try { + final response = await http.get(url); + if (response.statusCode == 200) { + setState(() { + chartsData = jsonDecode(response.body); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (error) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $error'); + } + } + + List parseLineChartData(List response) { + return response.map((entry) { + // Attempt to fetch the TIMEPERIOD + final rawTimePeriod = + entry['ObsKey']?['Year'] ?? entry['ObsKey']?['TIME_PERIOD']; + final formattedTimePeriod = rawTimePeriod != null + ? rawTimePeriod.toString() // Use as-is if valid + : 'Unknown'; // Fallback value if null + + // Parse the value or fallback to 0.0 + final value = + double.tryParse(entry['ObsValue']?['Value']?.toString() ?? '0.0') ?? + 0.0; + + return ChartData( + timePeriod: formattedTimePeriod, + value: value, + ); + }).toList(); + } + + List parseBarChartData(List response) { + return response + .asMap() + .entries + .map((entry) => ChartData( + timePeriod: entry.value['ObsKey']['TIME_PERIOD'] ?? + 'Unknown', // Fallback to 'Unknown' if null + value: double.tryParse( + entry.value['ObsValue']['Value'].toString()) ?? + 0.0, // Handle null/invalid value + )) + .toList(); + } + + Widget buildChart(dynamic chartData) { + print('chartData $chartData'); + switch (chartData['chart_type']) { + case 'line': + return SfCartesianChart( + primaryXAxis: CategoryAxis( + title: AxisTitle(text: 'Year'), + labelRotation: 45, // Rotate labels if they overlap + ), + title: ChartTitle(text: 'Hotel Estabhlishments'), + legend: Legend(isVisible: true), + tooltipBehavior: TooltipBehavior( + enable: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + '${data.timePeriod}: ${formatNumber(data.value)}', + style: const TextStyle(color: Colors.black), + ), + ); + }, + ), + series: >[ + LineSeries( + dataSource: parseLineChartData(chartData['response']), + xValueMapper: (ChartData data, _) => data.timePeriod, + yValueMapper: (ChartData data, _) => data.value, + name: chartData['dataset'], + color: Colors.red, + dataLabelSettings: DataLabelSettings( + isVisible: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Text( + formatNumber(data.value), + style: const TextStyle(fontSize: 12, color: Colors.black), + ); + }, + ), + ), + ], + ); + case 'bar': + return SfCartesianChart( + primaryXAxis: CategoryAxis(), + title: ChartTitle(text: 'Hotel Occupancy Rate'), + tooltipBehavior: TooltipBehavior( + enable: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + '${data.timePeriod}: ${formatNumber(data.value)}', + style: const TextStyle(color: Colors.black), + ), + ); + }, + ), + series: >[ + BarSeries( + dataSource: parseBarChartData(chartData['response']), + xValueMapper: (ChartData data, _) => data.timePeriod, + yValueMapper: (ChartData data, _) => data.value, + name: chartData['dataset'], + color: Colors.red, + dataLabelSettings: DataLabelSettings( + isVisible: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Text( + formatNumber(data.value), + style: const TextStyle(fontSize: 12, color: Colors.black), + ); + }, + ), + // isTrackVisible: true, + // trackColor: Colors.red + ), + ], + ); + default: + return Center(child: Text('Unknown chart type')); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF7DAFBC), + appBar: AppBar( + backgroundColor: Color(0xFF7DAFBC), + elevation: 0, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios_new, color: Colors.white), + onPressed: () { + context.go('/myhomepage'); + }, + ), + title: Text( + 'Charts', + style: TextStyle(color: Colors.white), + ), + ), + body: isLoading + ? Center(child: CircularProgressIndicator()) + : ListView.builder( + itemCount: chartsData.length, + itemBuilder: (context, index) { + return Card( + margin: EdgeInsets.all(10), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text( + // 'Chart: ${chartsData[index]['chart_type']}', + // style: TextStyle( + // fontSize: 18, fontWeight: FontWeight.bold), + // ), + // SizedBox(height: 10), + Container( + height: 300, + child: buildChart(chartsData[index]), + ), + ], + ), + ), + ); + }, + ), + ); + } +} + +class ChartData { + final String timePeriod; + final double value; + final String formattedValue; + + ChartData({required this.timePeriod, required this.value}) + : formattedValue = formatNumber(value); +} + +String formatNumber(double value) { + if (value >= 1e12) { + return '${(value / 1e12).toStringAsFixed(2)} T'; // Trillions + } else if (value >= 1e9) { + return '${(value / 1e9).toStringAsFixed(2)} B'; // Billions + } else if (value >= 1e6) { + return '${(value / 1e6).toStringAsFixed(2)} M'; // Millions + } else if (value >= 1e5) { + return '${(value / 1e5).toStringAsFixed(2)} L'; // Lakhs + } else if (value >= 1e3) { + return '${(value / 1e3).toStringAsFixed(2)} K'; // Thousands + } + return value.toStringAsFixed(2); // Default to two decimal places +} diff --git a/lib/presentation/Screens/profilepage.dart b/lib/presentation/Screens/profilepage.dart index 9c94e6ee..e003a18f 100644 --- a/lib/presentation/Screens/profilepage.dart +++ b/lib/presentation/Screens/profilepage.dart @@ -156,17 +156,39 @@ class _ProfileScreenState extends State { } } + // void _pickImage() async { + // final XFile? pickedFile = + // await _picker.pickImage(source: ImageSource.gallery); + // if (pickedFile != null) { + // setState(() { + // _profileImage = File(pickedFile.path); + // }); + // } + // } + + // Function to open the date picker + void _pickImage() async { final XFile? pickedFile = await _picker.pickImage(source: ImageSource.gallery); if (pickedFile != null) { - setState(() { - _profileImage = File(pickedFile.path); - }); + final String fileExtension = + pickedFile.path.split('.').last.toLowerCase(); + if (fileExtension == 'jpg' || + fileExtension == 'jpeg' || + fileExtension == 'png' || + fileExtension == "heic") { + setState(() { + _profileImage = File(pickedFile.path); + }); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Please select a JPG, JPEG, or PNG file.')), + ); + } } } - // Function to open the date picker Future _pickDate() async { final DateTime today = DateTime.now(); final DateTime initialDate = _selectedDate ?? @@ -273,11 +295,12 @@ class _ProfileScreenState extends State { _resetFormFields(); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Profile updated successfully!"))); - if (role == 'admin') { - context.go('/manageuser'); - } else { - context.go('/myhomepage'); - } + // if (role == 'admin') { + // context.go('/manageuser'); + // } else { + // context.go('/myhomepage'); + // } + context.go('/myhomepage'); } catch (error) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Failed to update profile: $error"))); @@ -370,8 +393,10 @@ class _ProfileScreenState extends State { children: [ Text( "User Name", - style: - TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -380,7 +405,7 @@ class _ProfileScreenState extends State { controller: _usernameController, focusNode: _focusNodes[0], decoration: InputDecoration( - hintText: _showHints[0] ? 'Mohammad Hassan' : null, + hintText: _showHints[0] ? 'Enter the User Name' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -393,9 +418,11 @@ class _ProfileScreenState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "E-mail", - style: - TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + "Email ID", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -418,7 +445,7 @@ class _ProfileScreenState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Full Name", + "Full Name*", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), @@ -444,7 +471,7 @@ class _ProfileScreenState extends State { controller: _fullNameController, focusNode: _focusNodes[2], decoration: InputDecoration( - hintText: _showHints[2] ? 'Enter the Full Name' : null, + hintText: _showHints[2] ? 'Enter the name' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -473,9 +500,9 @@ class _ProfileScreenState extends State { border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), - hintText: - _showHints[3] ? 'Select your Date of Birth' : null, - //hintText: 'Select your Date of Birth', + hintText: _showHints[3] ? 'DD/MM/YYYY' : null, + //_showHints[3] ? 'Select your Date of Birth' : null, + hintStyle: TextStyle(color: Colors.grey), suffixIcon: const Icon(Icons.arrow_drop_down_sharp), ), readOnly: true, diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index 7e56df9f..41dc0b37 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -256,12 +256,12 @@ class LoginRoute extends HookConsumerWidget { print(isProfileComplete); if (isProfileComplete) { print('home'); - if (role == 'admin') { - context.go('/manageuser'); - } else { - context.go('/myhomepage'); - } - // context.go('/myhomepage'); + // if (role == 'admin') { + // context.go('/myhomepage'); + // } else { + // context.go('/myhomepage'); + // } + context.go('/myhomepage'); } else { print('profile'); if (userId != null && userId.isNotEmpty) { diff --git a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart index 1c2fe332..cc4702c4 100644 --- a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart +++ b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart @@ -161,6 +161,7 @@ // } // } import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import '../../drawer_routes/custom_drawer_routes.dart'; class MyHomePage extends StatefulWidget { @@ -176,16 +177,16 @@ class _MyHomePageState extends State { double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; return BaseScaffold( - title: Center(child: SizedBox(height : myheight/5, width : mywidth/3,child: Image(image: AssetImage('assets/logos/uae_stat.png')))), + title: Center( + child: SizedBox( + height: myheight / 5, + width: mywidth / 3, + child: Image(image: AssetImage('assets/logos/uae_stat.png')))), body: EconomyStats(), ); } } - - - - class EconomyStats extends StatelessWidget { const EconomyStats({Key? key}) : super(key: key); @@ -193,24 +194,26 @@ class EconomyStats extends StatelessWidget { Widget build(BuildContext context) { return SingleChildScrollView( child: Padding( - padding: EdgeInsets.only(left: 10,right: 10), + padding: EdgeInsets.only(left: 10, right: 10), child: Column( children: [ // Header Section - RoundedCornerContainer( - text: 'ECONOMY', - backgroundColor: Color(0xFF7DAFBC), - textStyle: const TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), + RoundedCornerContainer( + text: 'ECONOMY', + backgroundColor: Color(0xFF7DAFBC), + textStyle: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), // Grid Section // ECONOMY DETAILS Padding( - padding: const EdgeInsets.only(top: 10,), + padding: const EdgeInsets.only( + top: 10, + ), child: Column( children: [ // First Row @@ -224,11 +227,12 @@ class EconomyStats extends StatelessWidget { bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), ), - InfoCard( + InfoCard( title: 'Inflation Rate', subtitle: '(2022)', value: '4.82%', - bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), + bordercolor: Color(0xFF7DAFBC), + textcolor: Color(0xFF7DAFBC), ), ], ), @@ -236,18 +240,20 @@ class EconomyStats extends StatelessWidget { // Second Row Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ + children: [ InfoCard( title: 'Trade Value', subtitle: '(Jan - Jan 2024) - AED', value: '215.4B', - bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), + bordercolor: Color(0xFF7DAFBC), + textcolor: Color(0xFF7DAFBC), ), InfoCard( title: 'Hotel Guests', subtitle: '(2022)', value: '25.21M', - bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), + bordercolor: Color(0xFF7DAFBC), + textcolor: Color(0xFF7DAFBC), ), ], ), @@ -264,7 +270,9 @@ class EconomyStats extends StatelessWidget { // SOCIAL DETAILS Padding( - padding: const EdgeInsets.only(top: 10,), + padding: const EdgeInsets.only( + top: 10, + ), child: Column( children: [ // First Row @@ -291,7 +299,7 @@ class EconomyStats extends StatelessWidget { // Second Row Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ + children: [ InfoCard( title: 'Hospitals (Gov )', subtitle: '(Jan - Jan 2024) - AED', @@ -321,12 +329,15 @@ class EconomyStats extends StatelessWidget { // ENVIRONMENT DETAILS Padding( - padding: const EdgeInsets.only(top: 10,), + padding: const EdgeInsets.only( + top: 10, + ), child: Column( children: [ // First Row Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, children: [ InfoCard( title: 'Electricity', @@ -347,8 +358,9 @@ class EconomyStats extends StatelessWidget { const SizedBox(height: 10), // Second Row Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ InfoCard( title: 'Export of oil', subtitle: '(Jan - Jan 2024) - AED', @@ -386,13 +398,11 @@ class RoundedCornerContainer extends StatelessWidget { final Color backgroundColor; final TextStyle? textStyle; - const RoundedCornerContainer({ Key? key, required this.text, this.backgroundColor = Colors.blue, this.textStyle, - }) : super(key: key); @override @@ -417,7 +427,6 @@ class RoundedCornerContainer extends StatelessWidget { } } - class InfoCard extends StatelessWidget { final String title; final String subtitle; @@ -425,60 +434,66 @@ class InfoCard extends StatelessWidget { final Color bordercolor; final Color? textcolor; - const InfoCard({ + const InfoCard({ Key? key, required this.title, required this.subtitle, - required this.value, required this.bordercolor,this.textcolor, + required this.value, + required this.bordercolor, + this.textcolor, }) : super(key: key); @override Widget build(BuildContext context) { double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; + return Expanded( - child: - Container( - height: myheight/9, - width: mywidth/4, - margin: const EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - border: Border.all(color: bordercolor), - borderRadius: BorderRadius.circular(8), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - child: Text( - title, - //textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.black, + child: GestureDetector( + onTap: () { + context.go('/DemoHome'); + }, + child: Container( + height: myheight / 9, + width: mywidth / 4, + margin: const EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + border: Border.all(color: bordercolor), + borderRadius: BorderRadius.circular(8), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Text( + title, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), ), ), - ), - const SizedBox(height: 2), - Text( - subtitle, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 12, - color: Colors.grey, + const SizedBox(height: 2), + Text( + subtitle, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 12, + color: Colors.grey, + ), ), - ), - const SizedBox(height: 2), - Text( - value, - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: textcolor ?? Colors.black + const SizedBox(height: 2), + Text( + value, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: textcolor ?? Colors.black, + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart index 00d0c486..8c513234 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -194,17 +194,39 @@ class _EditProfileState extends State { } } + // void _pickImage() async { + // final XFile? pickedFile = + // await _picker.pickImage(source: ImageSource.gallery); + // if (pickedFile != null) { + // setState(() { + // _profileImage = File(pickedFile.path); + // }); + // } + // } + + // Function to open the date picker + void _pickImage() async { final XFile? pickedFile = await _picker.pickImage(source: ImageSource.gallery); if (pickedFile != null) { - setState(() { - _profileImage = File(pickedFile.path); - }); + final String fileExtension = + pickedFile.path.split('.').last.toLowerCase(); + if (fileExtension == 'jpg' || + fileExtension == 'jpeg' || + fileExtension == 'png' || + fileExtension == "heic") { + setState(() { + _profileImage = File(pickedFile.path); + }); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Please select a JPG, JPEG, or PNG file.')), + ); + } } } - // Function to open the date picker Future _pickDate() async { final DateTime today = DateTime.now(); final DateTime initialDate = _selectedDate ?? @@ -398,7 +420,9 @@ class _EditProfileState extends State { Text( "User Name", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -407,7 +431,7 @@ class _EditProfileState extends State { controller: _usernameController, focusNode: _focusNodes[0], decoration: InputDecoration( - hintText: _showHints[0] ? 'Mohammad Hassan' : null, + // hintText: _showHints[0] ? 'Mohammad Hassan' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -420,9 +444,11 @@ class _EditProfileState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "E-mail", + "Email ID", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -431,10 +457,7 @@ class _EditProfileState extends State { controller: _emailController, focusNode: _focusNodes[1], decoration: InputDecoration( - hintText: _showHints[1] - ? 'mohammad.hassan@fcsc.gov.ae' - : null, - hintStyle: TextStyle(color: Colors.grey), + // hintText: _showHints[1]? 'mohammad.hassan@fcsc.gov.ae': null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), @@ -446,9 +469,11 @@ class _EditProfileState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Full Name", + "Full Name*", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -471,7 +496,7 @@ class _EditProfileState extends State { controller: _fullNameController, focusNode: _focusNodes[2], decoration: InputDecoration( - hintText: _showHints[2] ? 'Mohammad' : null, + // hintText: _showHints[2] ? 'Mohammad' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -490,7 +515,9 @@ class _EditProfileState extends State { Text( "Date of Birth*", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -502,10 +529,8 @@ class _EditProfileState extends State { border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), - hintText: _showHints[3] - ? 'Select your Date of Birth' - : null, - //hintText: 'Select your Date of Birth', + // hintText: _showHints[3] ? 'Select your Date of Birth' : null, + hintStyle: TextStyle(color: Colors.grey), suffixIcon: const Icon(Icons.arrow_drop_down_sharp), enabled: !_isProfileCompleted, ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart index deab917f..8652db61 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart @@ -43,7 +43,9 @@ class _ManageUserRouterState extends State { try { await _pb.admins .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); - final result = await _pb.collection('users').getFullList(); + final result = await _pb.collection('users').getFullList( + filter: 'role="user"', + ); setState(() { userData = result.map((record) { diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 981a32fe..8aa0afea 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -199,6 +199,15 @@ class _BaseScaffoldState extends State { title: Text('Manage User'), onTap: () => context.go('/manageuser'), ), + ListTile( + leading: SizedBox( + height: myheight / 15, + width: mywidth / 15, + child: Image( + image: AssetImage('assets/icons/drawer/logout.png'))), + title: Text('Logout'), + onTap: () => context.go('/'), + ), ], ), ), diff --git a/pubspec.lock b/pubspec.lock index 67247bd5..7d1ab196 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -841,6 +841,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.12.16+1" + material_charts: + dependency: "direct main" + description: + name: material_charts + sha256: "3950a910eeb8f5dca7040a68d526a086a9512f87da5c2b172495a5fcab0f6dc3" + url: "https://pub.dev" + source: hosted + version: "0.0.23" material_color_utilities: dependency: transitive description: @@ -1501,5 +1509,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.5.0 <4.0.0" + dart: ">=3.5.2 <4.0.0" flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3fac9859..ebd8679b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,6 +55,7 @@ dependencies: mailer: ^6.2.0 image_picker: ^1.1.2 syncfusion_flutter_charts: ^28.1.33 + material_charts: ^0.0.23 dependency_overrides: fading_edge_scrollview: ^4.1.1