diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index 731091d5..9f847904 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -295,6 +295,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:go_router/go_router.dart'; +import 'package:uae_stat/config/sessionCheckScreen.dart'; import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/UAE_Numbers/Social/marriages.dart'; import 'package:uae_stat/presentation/Screens/auth_verification/registration.dart'; import 'package:uae_stat/presentation/Screens/charts/chart.dart'; @@ -336,34 +337,35 @@ import '../presentation/routes/drawer_routes/Drawer Items/manage_users.dart'; final FlutterSecureStorage _secureStorage = const FlutterSecureStorage(); -Future _checkSession() async { - print('_checkSession'); - await Future.delayed(Duration(seconds: 2)); // Optional splash effect - - String? sessionToken = - await _secureStorage.read(key: "FlutterSecureStorage.session"); - print('sessionToken $sessionToken'); - - if (sessionToken != null && sessionToken.isNotEmpty) { - print('_checkSession home'); - return "/myhomepage"; // Redirect to home page if session is valid - } else { - print('_checkSession login'); - return "/login"; // Redirect to login page if session is invalid - } -} +// Future _checkSession() async { +// print('_checkSession'); +// await Future.delayed(Duration(seconds: 2)); // Optional splash effect +// +// String? sessionToken = +// await _secureStorage.read(key: "FlutterSecureStorage.session"); +// print('sessionToken $sessionToken'); +// +// if (sessionToken != null && sessionToken.isNotEmpty) { +// print('_checkSession home'); +// return "/myhomepage"; // Redirect to home page if session is valid +// } else { +// print('_checkSession login'); +// return "/login"; // Redirect to login page if session is invalid +// } +// } final GoRouter router = GoRouter( + initialLocation: '/', routes: [ - // GoRoute( - // path: '/', - // //builder: (context, state) => LoginRoute(), - // builder: (context, state) => LoginRoute(), - // ), GoRoute( path: '/', - redirect: (context, state) async => await _checkSession(), + //builder: (context, state) => LoginRoute(), + builder: (context, state) => SessionCheckScreen(), ), + // GoRoute( + // path: '/', + // redirect: (context, state) async => await _checkSession(), + // ), GoRoute( path: '/internetcheck', builder: (context, state) => InternetCheck(), diff --git a/lib/config/sessionCheckScreen.dart b/lib/config/sessionCheckScreen.dart new file mode 100644 index 00000000..dbe3af06 --- /dev/null +++ b/lib/config/sessionCheckScreen.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; + +class SessionCheckScreen extends StatefulWidget { + @override + _SessionCheckScreenState createState() => _SessionCheckScreenState(); +} + +class _SessionCheckScreenState extends State { + final PAuthRepo _authRepo = PAuthRepo(); + + @override + void initState() { + super.initState(); + _checkSession(); + } + + Future _checkSession() async { + await Future.delayed(Duration(seconds: 2)); // Optional splash delay + print('fetchLocallyStored'); + final session = await _authRepo.fetchLocallyStored(); + print('fetchLocallyStored $session'); + if (session != null) { + print('myhomepage'); + if (mounted) context.go('/myhomepage'); // Redirect to home + } else { + print('login'); + if (mounted) context.go('/login'); // Redirect to login + } + } + + @override + Widget build(BuildContext context) { + return SizedBox.shrink(); + } +} diff --git a/lib/l10n/intl_ar.arb b/lib/l10n/intl_ar.arb index 2834090b..379d7b69 100644 --- a/lib/l10n/intl_ar.arb +++ b/lib/l10n/intl_ar.arb @@ -69,7 +69,7 @@ "password_match": "كلمات المرور غير متطابقة", "only8charac": "يجب أن تتكون كلمة المرور من 8 أحرف على الأقل", - "manage_user": "إدارة المستخدمين", + "manage_user": "إدارة المستخدم", "user_name": "اسم المستخدم", "reg_date": "تاريخ التسجيل", "status": "الحالة", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index e4efd016..bb3e4604 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -71,7 +71,7 @@ "password_match": "Passwords do not match", "only8charac": "Password must be at least 8characters", - "manage_user": "Manage user", + "manage_user": "Manage User", "user_name": "User Name", "reg_date": "Registration Date", "status": "Status", diff --git a/lib/presentation/Screens/Bottom Navigation Pages/Competitiveness/competitiveness.dart b/lib/presentation/Screens/Bottom Navigation Pages/Competitiveness/competitiveness.dart index 57ec518d..e2965362 100644 --- a/lib/presentation/Screens/Bottom Navigation Pages/Competitiveness/competitiveness.dart +++ b/lib/presentation/Screens/Bottom Navigation Pages/Competitiveness/competitiveness.dart @@ -10,9 +10,10 @@ class Competitiveness extends StatelessWidget { double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/myhomepage'); + context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( title: Center( diff --git a/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart b/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart index a08720a0..86f01ed2 100644 --- a/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart +++ b/lib/presentation/Screens/Bottom Navigation Pages/Country_Profile/country_profile.dart @@ -11,9 +11,10 @@ class CountryProfile extends StatelessWidget { double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/myhomepage'); + context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( title: Center( diff --git a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart index ce3ef28f..210b9163 100644 --- a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart +++ b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; @@ -31,12 +32,16 @@ class UaeNumbers extends StatelessWidget { double mywidth = MediaQuery.of(context).size.width; return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/myhomepage'); + context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( - title: Text("UAE Numbers"), + title: Text(context.translate( + 'UAE Numbers', + 'أرقام الإمارات', + )), body: uaenumberWidget(), ), ); @@ -107,9 +112,9 @@ class _UaenumberWidgetState extends ConsumerState { decoration: InputDecoration( hintText: "Search", prefixIcon: Image.asset( - MiscIconAssetPath.search, - width: 20, - height: 20, + MiscIconAssetPath.search, + width: 20, + height: 20, ), border: InputBorder.none, contentPadding: @@ -389,9 +394,9 @@ class _CustomExpandableTileState extends State { ? SingleChildScrollView( child: Container( decoration: BoxDecoration( - color: Colors.white, - // borderRadius: BorderRadius.all(Radius.circular(20)) - ), + color: Colors.white, + // borderRadius: BorderRadius.all(Radius.circular(20)) + ), padding: const EdgeInsets.all(1), child: Column( children: widget.children, diff --git a/lib/presentation/Screens/auth_verification/registration.dart b/lib/presentation/Screens/auth_verification/registration.dart index 7e33bbba..3bc5fa71 100644 --- a/lib/presentation/Screens/auth_verification/registration.dart +++ b/lib/presentation/Screens/auth_verification/registration.dart @@ -336,747 +336,864 @@ class _RegisterScreenState extends ConsumerState { ); } - return Scaffold( - - body: - - Column( - children: [ - Align( - alignment: AlignmentDirectional.topEnd, - child: Consumer( - builder: (context, ref, _) { - final locale = ref.watch(localeProvider); // Current locale - return MyToggle( - isOn: locale?.languageCode == 'en', - knobTextWhenOn: 'ع', - knobTextWhenOff: 'EN', - pathColorWhenOn: Colors.grey.shade300, - pathColorWhenOff: Colors.grey.shade300, - onTap: () { - ref.read(localeProvider.notifier).toggleLocale(); - }, - ); - // IconButton( - // icon: Icon(locale?.languageCode == 'en' - // ? Icons.toggle_off_outlined - // : Icons.toggle_on_outlined,), - // onPressed: () { - // ref.read(localeProvider.notifier).toggleLocale(); - // }, - // ); - }, + return PopScope( + canPop: false, // Allow back navigation only if not login screen + onPopInvokedWithResult: (didPop, result) { + if (didPop) return; + context.go('/login'); // Show exit confirmation dialog + }, + child: Scaffold( + body: Column( + children: [ + Align( + alignment: AlignmentDirectional.topEnd, + child: Consumer( + builder: (context, ref, _) { + final locale = ref.watch(localeProvider); // Current locale + return MyToggle( + isOn: locale?.languageCode == 'en', + knobTextWhenOn: 'ع', + knobTextWhenOff: 'EN', + pathColorWhenOn: Colors.grey.shade300, + pathColorWhenOff: Colors.grey.shade300, + onTap: () { + ref.read(localeProvider.notifier).toggleLocale(); + }, + ); + // IconButton( + // icon: Icon(locale?.languageCode == 'en' + // ? Icons.toggle_off_outlined + // : Icons.toggle_on_outlined,), + // onPressed: () { + // ref.read(localeProvider.notifier).toggleLocale(); + // }, + // ); + }, + ), ), - ), - Container( - height: MediaQuery.of(context).size.height/1.2, - child: SingleChildScrollView( - child: Column( - children : [ - + Container( + height: MediaQuery.of(context).size.height / 1.2, + child: SingleChildScrollView( + child: Column(children: [ registrationSuccess - ? Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: screenheight / 8), - buildIconContainer(Icons.report, Color(0xFF7DAFBC)), - SizedBox(height: 20), - Text( - context.translate( - 'Your registration is pending for verification.', - 'تسجيلك في انتظار التحقق.'), - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF414042)), - ), - SizedBox(height: 10), - Text( - context.translate( - 'Kindly verify your mail to proceed further.', - 'يرجى التحقق من البريد الخاص بك للمضي قدما.'), - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14, - color: Color(0xFF898C81), + ? Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: screenheight / 8), + buildIconContainer( + Icons.report, Color(0xFF7DAFBC)), + SizedBox(height: 20), + Text( + context.translate( + 'Your registration is pending for verification.', + 'تسجيلك في انتظار التحقق.'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Color(0xFF414042)), ), - ), - SizedBox(height: 10), - ElevatedButton( - onPressed: () => {context.go('/')}, - child: Text( - context.translate('Go to Login', 'اذهب إلى تسجيل الدخول'), - ), - ), - SizedBox(height: screenheight / 5), - Center( - child: Container( - height: screenheight / 16, - width: screenwidth / 2.5, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "assets/splash_screen/logo.png"), // Background image asset - fit: BoxFit.fill, + SizedBox(height: 10), + Text( + context.translate( + 'Kindly verify your mail to proceed further.', + 'يرجى التحقق من البريد الخاص بك للمضي قدما.'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14, + color: Color(0xFF898C81), ), ), - )) - ], - ), - ) - : registrationFailed - ? Padding( - padding: const EdgeInsets.all(20.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: screenheight / 8), - buildIconContainer(Icons.report, Colors.red), - SizedBox(height: 20), - Text( - context.translate('Sorry ${_usernameController.text}!', - 'آسف ${_usernameController.text}!'), - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF414042)), - ), - SizedBox(height: 10), - Text( + SizedBox(height: 10), + ElevatedButton( + onPressed: () => {context.go('/')}, + child: Text( context.translate( - 'Your registration process failed. For further assistance, please contact support.', - 'فشلت عملية التسجيل الخاصة بك. لمزيد من المساعدة، يرجى الاتصال بالدعم.'), - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14, - color: Color(0xFF898C81), + 'Go to Login', 'اذهب إلى تسجيل الدخول'), + ), + ), + SizedBox(height: screenheight / 5), + Center( + child: Container( + height: screenheight / 16, + width: screenwidth / 2.5, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + "assets/splash_screen/logo.png"), // Background image asset + fit: BoxFit.fill, ), ), - SizedBox(height: 10), - ElevatedButton( - onPressed: () => { - setState(() { - registrationFailed = false; - registrationSuccess = false; - _usernameController.clear(); - _emailController.clear(); - _passwordController.clear(); - _confirmpasswordController.clear(); - isChecked = false; - }) - }, - child: Text( - context.translate('Retry', 'أعد المحاولة'), + )) + ], + ), + ) + : registrationFailed + ? Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: screenheight / 8), + buildIconContainer(Icons.report, Colors.red), + SizedBox(height: 20), + Text( + context.translate( + 'Sorry ${_usernameController.text}!', + 'آسف ${_usernameController.text}!'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Color(0xFF414042)), ), - ), - SizedBox(height: screenheight / 5), - Center( - child: Container( - height: screenheight / 16, - width: screenwidth / 2.5, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "assets/splash_screen/logo.png"), // Background image asset - fit: BoxFit.fill, + SizedBox(height: 10), + Text( + context.translate( + 'Your registration process failed. For further assistance, please contact support.', + 'فشلت عملية التسجيل الخاصة بك. لمزيد من المساعدة، يرجى الاتصال بالدعم.'), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14, + color: Color(0xFF898C81), ), ), - )) - ], - ), - ) - - : Form( - key: _formKey, - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: screenheight / 60), - Text( - // 'Register', - AppLocalizations.of(context)!.register_title, - style: TextStyle( - fontSize: 32, fontWeight: FontWeight.w400), - ), - SizedBox(height: 10), - Text(AppLocalizations.of(context)!.register_details), - - SizedBox(height: 20), - // Display this if registration is pending approval - Padding( - padding: const EdgeInsets.only( - top: 5.0, bottom: 10, left: 30, right: 30), - child: TextFormField( - controller: _usernameController, - // focusNode: _focusNodes[0], - decoration: InputDecoration( - // hintText: _showHints[0] ? 'Username' : null, - hintText: _showHints[0] - ? AppLocalizations.of(context)!.register_name - : null, - prefixIconConstraints: const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: const EdgeInsetsDirectional.only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.person, - fit: BoxFit.fitHeight, - height: 25, - width: 25, - color: - MyTheme.topicColor(IndicatorTopic.economy) - .shade300, - ), - ), - - // prefixIcon: Icon( - // Icons.person, - // color: Color(0xFF90B0D5), - // - // ), - // border: OutlineInputBorder(), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: MyTheme.topicColor( - IndicatorTopic.economy) - .shade400, - width: 1), // Enabled border - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Colors.deepPurple, - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Error border - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Match the error color - ), - counterText: '', - hintStyle: TextStyle(color: Color(0xFFC3C6CB), - fontSize: registerLocale?.languageCode == 'ar' ? 14 : 16, - ), - ), - validator: _validateUsername, - maxLength: - 40, // Set the maximum length to 20 characters - maxLengthEnforcement: MaxLengthEnforcement.enforced, - ), - ), - SizedBox(height: 15), - Padding( - padding: const EdgeInsets.only( - top: 5.0, bottom: 10, left: 30, right: 30), - child: TextFormField( - controller: _emailController, - // focusNode: _focusNodes[1], - decoration: InputDecoration( - // hintText: 'Enter your email', - hintText: _showHints[1] - ? AppLocalizations.of(context)! - .enter_your_email - : null, - // _showHints[1] ? 'Enter your email' : null, - prefixIconConstraints: const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: const EdgeInsetsDirectional.only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.vector, - fit: BoxFit.fitHeight, - height: 20, - width: 25, - color: - MyTheme.topicColor(IndicatorTopic.economy) - .shade100, - ), - ), - - // border: OutlineInputBorder(), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: MyTheme.topicColor( - IndicatorTopic.economy) - .shade400, - width: 1), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Colors.deepPurple, - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Error border - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Match the error color - ), - counterText: '', - hintStyle: TextStyle(color: Color(0xFFC3C6CB), - fontSize: registerLocale?.languageCode == 'ar' ? 14 : 16, - ), - ), - validator: _validateEmail, - maxLength: 320, - maxLengthEnforcement: MaxLengthEnforcement.enforced, - inputFormatters: [ - LengthLimitingTextInputFormatter( - 320), // Limit to 320 characters - ], - ), - ), - SizedBox(height: 15), - Padding( - padding: const EdgeInsets.only( - top: 5.0, bottom: 10, left: 30, right: 30), - child: TextFormField( - controller: _passwordController, - // focusNode: _focusNodes[2], - obscureText: _obscurePassword, - decoration: InputDecoration( - hintText: _showHints[2] - ? AppLocalizations.of(context)! - .enter_your_password - : null, - // _showHints[2] ? 'Enter your password' : null, - prefixIconConstraints: const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: const EdgeInsetsDirectional.only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.lock, - fit: BoxFit.fitHeight, - height: 25, - width: 25, - color: - MyTheme.topicColor(IndicatorTopic.economy) - .shade300, - ), - ), - - // prefixIcon: Icon( - // Icons.lock, - // color: Color(0xFF90B0D5), - // ), - suffixIcon: IconButton( - // icon: Icon( - // _obscurePassword - // ? Icons.visibility_off - // : Icons.visibility, - // color: Color(0xFF9EA2A9), - // ), - - icon: Image.asset( - _obscurePassword - ? MiscIconAssetPath.visibilityOff - : MiscIconAssetPath.visibleOn, - - color: Color( - 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. - width: 24, - height: 24, - ), - - onPressed: () { - setState(() { - _obscurePassword = !_obscurePassword; - }); - }, - ), - // border: OutlineInputBorder(), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: MyTheme.topicColor( - IndicatorTopic.economy) - .shade400, - width: 1), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Colors.deepPurple, - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Error border - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Match the error color - ), - - counterText: '', - hintStyle: TextStyle(color: Color(0xFFC3C6CB), - fontSize: registerLocale?.languageCode == 'ar' ? 14 : 16, - ), - ), - validator: _validatePassword, - maxLength: 40, - maxLengthEnforcement: MaxLengthEnforcement.enforced, - ), - ), - SizedBox(height: 15), - Padding( - padding: const EdgeInsets.only( - top: 5.0, bottom: 10, left: 30, right: 30), - child: TextFormField( - controller: _confirmpasswordController, - // focusNode: _focusNodes[3], - obscureText: _obscureConfirmPassword, - decoration: InputDecoration( - hintText: _showHints[3] - ? AppLocalizations.of(context)! - .register_Confirm_password - : null, - // _showHints[3] ? 'Confirm password' : null, - prefixIconConstraints: const BoxConstraints( - maxWidth: 25 + 16 + 10, - maxHeight: 25 + (8 * 2), - ), - prefixIcon: Padding( - padding: const EdgeInsetsDirectional.only( - start: 16, - end: 10, - ), - child: Image.asset( - MiscIconAssetPath.lock, - fit: BoxFit.fitHeight, - height: 25, - width: 25, - color: - MyTheme.topicColor(IndicatorTopic.economy) - .shade300, - ), - ), - - suffixIcon: IconButton( - icon: Image.asset( - _obscureConfirmPassword - ? MiscIconAssetPath.visibilityOff - : MiscIconAssetPath.visibleOn, - - color: Color( - 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. - width: 24, - height: 24, - ), - onPressed: () { - setState(() { - _obscureConfirmPassword = - !_obscureConfirmPassword; - }); - }, - ), - // border: OutlineInputBorder( - // borderSide: BorderSide(color: Colors.blue, width: 2), // Default border color - // ), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: MyTheme.topicColor( - IndicatorTopic.economy) - .shade400, - width: 1), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Colors.deepPurple, - width: 2), // Focused border - ), - errorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Error border - ), - focusedErrorBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Color(0xFFb22222), - width: 1), // Match the error color - ), - counterText: '', - hintStyle: TextStyle(color: Color(0xFFC3C6CB), - fontSize: registerLocale?.languageCode == 'ar' ? 14 : 16, - ), - ), - validator: _validateConfirmPassword, - maxLength: 40, - maxLengthEnforcement: MaxLengthEnforcement.enforced, - inputFormatters: [ - LengthLimitingTextInputFormatter( - 64), // Limit to 40 characters - ], - ), - ), - SizedBox(height: 10), - Padding( - padding: const EdgeInsets.only( - top: 0, bottom: 10, left: 25, right: 30), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Checkbox( - value: isChecked, - onChanged: (value) { - setState(() { - isChecked = value ?? false; - showError = false; - }); - }, - side: BorderSide( - color: showError - ? Color(0xFFD83731) - : Color(0xFF7DAFBC), - width: 1, - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.only(top:11.0), - child: Text.rich( - TextSpan( - text: AppLocalizations.of(context)!.agree, - // text: 'I agree to ', - style: TextStyle( - color: Color(0xFF898C81), // Change to your desired color + SizedBox(height: 10), + ElevatedButton( + onPressed: () => { + setState(() { + registrationFailed = false; + registrationSuccess = false; + _usernameController.clear(); + _emailController.clear(); + _passwordController.clear(); + _confirmpasswordController.clear(); + isChecked = false; + }) + }, + child: Text( + context.translate( + 'Retry', 'أعد المحاولة'), ), + ), + SizedBox(height: screenheight / 5), + Center( + child: Container( + height: screenheight / 16, + width: screenwidth / 2.5, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + "assets/splash_screen/logo.png"), // Background image asset + fit: BoxFit.fill, + ), + ), + )) + ], + ), + ) + : Form( + key: _formKey, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - TextSpan( - text: AppLocalizations.of(context)! - .terms_conditions, - // text: 'Terms & Conditions', + SizedBox(height: screenheight / 60), + Text( + // 'Register', + AppLocalizations.of(context)! + .register_title, style: TextStyle( - fontSize: registerLocale?.languageCode == 'ar' ? 12 : 14, - fontWeight: FontWeight.bold, - color: Color(0xFF985400), - // Makes the text bold - // decoration: - // TextDecoration.underline, - decorationColor: Color(0xFF985400), - decorationThickness: 1), + fontSize: 32, + fontWeight: FontWeight.w400), ), - TextSpan( - text: AppLocalizations.of(context)! - .t_and, - style: TextStyle( - color: Color(0xFF898C81), // Change to your desired color - ),), - TextSpan( - text: AppLocalizations.of(context)! - .privacy_policy, + SizedBox(height: 10), + Text(AppLocalizations.of(context)! + .register_details), + + SizedBox(height: 20), + // Display this if registration is pending approval + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: _usernameController, + // focusNode: _focusNodes[0], + decoration: InputDecoration( + // hintText: _showHints[0] ? 'Username' : null, + hintText: _showHints[0] + ? AppLocalizations.of(context)! + .register_name + : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), + ), + prefixIcon: Padding( + padding: const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.person, + fit: BoxFit.fitHeight, + height: 25, + width: 25, + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade300, + ), + ), + + // prefixIcon: Icon( + // Icons.person, + // color: Color(0xFF90B0D5), + // + // ), + // border: OutlineInputBorder(), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade400, + width: 1), // Enabled border + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Colors.deepPurple, + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: + 1), // Match the error color + ), + counterText: '', + hintStyle: TextStyle( + color: Color(0xFFC3C6CB), + fontSize: + registerLocale?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validateUsername, + maxLength: + 40, // Set the maximum length to 20 characters + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + ), + ), + SizedBox(height: 15), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: _emailController, + // focusNode: _focusNodes[1], + decoration: InputDecoration( + // hintText: 'Enter your email', + hintText: _showHints[1] + ? AppLocalizations.of(context)! + .enter_your_email + : null, + // _showHints[1] ? 'Enter your email' : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), + ), + prefixIcon: Padding( + padding: const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.vector, + fit: BoxFit.fitHeight, + height: 20, + width: 25, + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade100, + ), + ), + + // border: OutlineInputBorder(), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade400, + width: 1), + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Colors.deepPurple, + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: + 1), // Match the error color + ), + counterText: '', + hintStyle: TextStyle( + color: Color(0xFFC3C6CB), + fontSize: + registerLocale?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validateEmail, + maxLength: 320, + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + inputFormatters: [ + LengthLimitingTextInputFormatter( + 320), // Limit to 320 characters + ], + ), + ), + SizedBox(height: 15), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: _passwordController, + // focusNode: _focusNodes[2], + obscureText: _obscurePassword, + decoration: InputDecoration( + hintText: _showHints[2] + ? AppLocalizations.of(context)! + .enter_your_password + : null, + // _showHints[2] ? 'Enter your password' : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), + ), + prefixIcon: Padding( + padding: const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.lock, + fit: BoxFit.fitHeight, + height: 25, + width: 25, + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade300, + ), + ), + + // prefixIcon: Icon( + // Icons.lock, + // color: Color(0xFF90B0D5), + // ), + suffixIcon: IconButton( + // icon: Icon( + // _obscurePassword + // ? Icons.visibility_off + // : Icons.visibility, + // color: Color(0xFF9EA2A9), + // ), + + icon: Image.asset( + _obscurePassword + ? MiscIconAssetPath + .visibilityOff + : MiscIconAssetPath.visibleOn, + + color: Color( + 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. + width: 24, + height: 24, + ), + + onPressed: () { + setState(() { + _obscurePassword = + !_obscurePassword; + }); + }, + ), + // border: OutlineInputBorder(), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade400, + width: 1), + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Colors.deepPurple, + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: + 1), // Match the error color + ), + + counterText: '', + hintStyle: TextStyle( + color: Color(0xFFC3C6CB), + fontSize: + registerLocale?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validatePassword, + maxLength: 40, + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + ), + ), + SizedBox(height: 15), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: TextFormField( + controller: _confirmpasswordController, + // focusNode: _focusNodes[3], + obscureText: _obscureConfirmPassword, + decoration: InputDecoration( + hintText: _showHints[3] + ? AppLocalizations.of(context)! + .register_Confirm_password + : null, + // _showHints[3] ? 'Confirm password' : null, + prefixIconConstraints: + const BoxConstraints( + maxWidth: 25 + 16 + 10, + maxHeight: 25 + (8 * 2), + ), + prefixIcon: Padding( + padding: const EdgeInsetsDirectional + .only( + start: 16, + end: 10, + ), + child: Image.asset( + MiscIconAssetPath.lock, + fit: BoxFit.fitHeight, + height: 25, + width: 25, + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade300, + ), + ), + + suffixIcon: IconButton( + icon: Image.asset( + _obscureConfirmPassword + ? MiscIconAssetPath + .visibilityOff + : MiscIconAssetPath.visibleOn, + + color: Color( + 0xFF9EA2A9), // Apply color if needed, but keep in mind `Image.asset` might not support color directly. + width: 24, + height: 24, + ), + onPressed: () { + setState(() { + _obscureConfirmPassword = + !_obscureConfirmPassword; + }); + }, + ), + // border: OutlineInputBorder( + // borderSide: BorderSide(color: Colors.blue, width: 2), // Default border color + // ), + enabledBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: MyTheme.topicColor( + IndicatorTopic.economy) + .shade400, + width: 1), + ), + focusedBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Colors.deepPurple, + width: 2), // Focused border + ), + errorBorder: OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: 1), // Error border + ), + focusedErrorBorder: + OutlineInputBorder( + borderRadius: + BorderRadius.circular(10), + borderSide: BorderSide( + color: Color(0xFFb22222), + width: + 1), // Match the error color + ), + counterText: '', + hintStyle: TextStyle( + color: Color(0xFFC3C6CB), + fontSize: + registerLocale?.languageCode == + 'ar' + ? 14 + : 16, + ), + ), + validator: _validateConfirmPassword, + maxLength: 40, + maxLengthEnforcement: + MaxLengthEnforcement.enforced, + inputFormatters: [ + LengthLimitingTextInputFormatter( + 64), // Limit to 40 characters + ], + ), + ), + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only( + top: 0, + bottom: 10, + left: 25, + right: 30), + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Checkbox( + value: isChecked, + onChanged: (value) { + setState(() { + isChecked = value ?? false; + showError = false; + }); + }, + side: BorderSide( + color: showError + ? Color(0xFFD83731) + : Color(0xFF7DAFBC), + width: 1, + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + top: 11.0), + child: Text.rich( + TextSpan( + text: AppLocalizations.of( + context)! + .agree, + // text: 'I agree to ', + style: TextStyle( + color: Color( + 0xFF898C81), // Change to your desired color + ), + children: [ + TextSpan( + text: AppLocalizations.of( + context)! + .terms_conditions, + // text: 'Terms & Conditions', + style: TextStyle( + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 12 + : 14, + fontWeight: + FontWeight.bold, + color: + Color(0xFF985400), + // Makes the text bold + // decoration: + // TextDecoration.underline, + decorationColor: + Color(0xFF985400), + decorationThickness: + 1), + ), + TextSpan( + text: AppLocalizations.of( + context)! + .t_and, + style: TextStyle( + color: Color( + 0xFF898C81), // Change to your desired color + ), + ), + TextSpan( + text: AppLocalizations.of( + context)! + .privacy_policy, + style: TextStyle( + fontWeight: + FontWeight.bold, + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 12 + : 14, + fontFamily: 'Roboto', + color: + Color(0xFF985400), + // decoration: + // TextDecoration.underline, + decorationColor: + Color(0xFF648CBA), + decorationThickness: + 1), + ), + TextSpan( + text: AppLocalizations.of( + context)! + .conditions, + style: TextStyle( + color: Color( + 0xFF898C81), // Change to your desired color + ), + ), + ], + ), + ), + ), + ), + ], + ), + ), + if (showError) + Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 30.0), + child: Text( + 'Required', + style: TextStyle( + color: Color(0xFFb22222), + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 12 + : 14, + ), + ), + ), + ], + ), + SizedBox(height: 20), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: SizedBox( + width: screenwidth / 1, + child: ElevatedButton( + onPressed: isRegistering + ? null + : _registerUser, + style: ElevatedButton.styleFrom( + backgroundColor: Color( + 0xFFA7887A), // Brownish color for Register + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(10), + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + // "Register", + AppLocalizations.of(context)! + .register_title, + style: TextStyle( + fontSize: registerLocale + ?.languageCode == + 'ar' + ? 14 + : 16, + color: Colors.white), + ), + SizedBox(width: 8), + const Icon( + Icons.chevron_right_outlined, + color: Colors + .white, // Set your desired color here + ) + ], + ), + ), + ), + ), + SizedBox(height: 15), + Text( + AppLocalizations.of(context)! + .account_confirmation, style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: registerLocale?.languageCode == 'ar' ? 12 : 14, - fontFamily: 'Roboto', - color: Color(0xFF985400), - // decoration: - // TextDecoration.underline, - decorationColor: Color(0xFF648CBA), - decorationThickness: 1), + fontSize: + registerLocale?.languageCode == + 'ar' + ? 12 + : 14, + color: Colors.grey[600]), + ), + SizedBox(height: 15), + Padding( + padding: const EdgeInsets.only( + top: 5.0, + bottom: 10, + left: 30, + right: 30), + child: SizedBox( + width: screenwidth / 1, + child: ElevatedButton( + onPressed: () { + context.go('/'); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Color( + 0xFF82AFCB), // Blueish color for Login + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(10), + ), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + AppLocalizations.of(context)! + .login_title, + style: TextStyle( + fontSize: 16, + color: Colors.white), + ), + SizedBox(width: 8), + const Icon( + Icons.chevron_right_outlined, + color: Colors + .white, // Set your desired color here + ) + ], + ), + ), + ), + ), + SizedBox( + height: 10, + ), + Center( + child: Container( + height: screenheight / 16, + width: screenwidth / 3, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage( + "assets/splash_screen/logo.png"), // Background image asset + fit: BoxFit.fill, + ), + ), + )), + SizedBox( + height: 20, ), - TextSpan( - text: AppLocalizations.of(context)! - .conditions, - style: TextStyle( - color: Color(0xFF898C81), // Change to your desired color - ),), ], ), - ), ), ), - ], - ), - ), - if (showError) - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(left: 30.0), - child: Text( - 'Required', - style: TextStyle( - color: Color(0xFFb22222), - fontSize: registerLocale?.languageCode == 'ar' ? 12 : 14, - ), - ), - ), - ], - ), - SizedBox(height: 20), - Padding( - padding: const EdgeInsets.only( - top: 5.0, bottom: 10, left: 30, right: 30), - child: SizedBox( - width: screenwidth / 1, - child: ElevatedButton( - onPressed: isRegistering ? null : _registerUser, - style: ElevatedButton.styleFrom( - backgroundColor: Color( - 0xFFA7887A), // Brownish color for Register - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - // "Register", - AppLocalizations.of(context)! - .register_title, - style: TextStyle( - fontSize: registerLocale?.languageCode == 'ar' ? 14 : 16, - color: Colors.white), - ), - SizedBox(width: 8), - const Icon( - Icons.chevron_right_outlined, - color: Colors - .white, // Set your desired color here - ) - ], - ), - ), - ), - ), - SizedBox(height: 15), - Text( - AppLocalizations.of(context)!.account_confirmation, - style: TextStyle( - fontSize: registerLocale?.languageCode == 'ar' ? 12 : 14, - color: Colors.grey[600]), - ), - SizedBox(height: 15), - Padding( - padding: const EdgeInsets.only( - top: 5.0, bottom: 10, left: 30, right: 30), - child: SizedBox( - width: screenwidth / 1, - child: ElevatedButton( - onPressed: () { - context.go('/'); - }, - style: ElevatedButton.styleFrom( - backgroundColor: Color( - 0xFF82AFCB), // Blueish color for Login - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - AppLocalizations.of(context)!.login_title, - style: TextStyle( - fontSize: 16, color: Colors.white), - ), - SizedBox(width: 8), - const Icon( - Icons.chevron_right_outlined, - color: Colors - .white, // Set your desired color here - ) - ], - ), - - // 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( - height: 10, - ), - Center( - child: Container( - height: screenheight / 16, - width: screenwidth / 3, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "assets/splash_screen/logo.png"), // Background image asset - fit: BoxFit.fill, - ), - ), - )), - SizedBox( - height: 20, - ), - ], - ), - ), - ), - ]), + ]), + ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/presentation/Screens/profilepage.dart b/lib/presentation/Screens/profilepage.dart index 51d6605a..873bf04f 100644 --- a/lib/presentation/Screens/profilepage.dart +++ b/lib/presentation/Screens/profilepage.dart @@ -9,7 +9,9 @@ import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; import 'package:pocketbase/pocketbase.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -336,12 +338,62 @@ class _ProfileScreenState extends State { }); } + final PAuthRepo _authRepo = PAuthRepo(); + + Future logout(BuildContext context) async { + final prefs = await SharedPreferences.getInstance(); + await _authRepo.logout(); + prefs.clear(); + context.go('/login'); // Redirect to login after logout + } + + void _showExitConfirmation(BuildContext context) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text( + context.translate( + 'Logout', + 'تسجيل الخروج', + ), + ), + content: Text( + context.translate( + 'Are you sure you want to logout?', + 'هل أنت متأكد أنك تريد تسجيل الخروج؟', + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), // Close dialog + child: Text( + context.translate( + 'Cancel', + 'إلغاء', + ), + ), + ), + TextButton( + onPressed: () => logout(context), // Exit the app + child: Text( + context.translate( + 'Logout', + 'تسجيل الخروج', + ), + ), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/'); + _showExitConfirmation(context); // Show exit confirmation dialog }, child: Scaffold( appBar: AppBar( @@ -632,7 +684,7 @@ class _ProfileScreenState extends State { }, side: BorderSide( color: - showError ? Color(0xFFb22222) : Color(0xFF7296BE), + showError ? Color(0xFFb22222) : Color(0xFF7296BE), width: 1, ), ), @@ -646,16 +698,15 @@ class _ProfileScreenState extends State { ), Text.rich( TextSpan( - text: AppLocalizations.of( - context)! - .agree, - style: TextStyle(color: Color(0xFF898C81)), + text: AppLocalizations.of(context)!.agree, + style: TextStyle(color: Color(0xFF898C81)), children: [ TextSpan( text: AppLocalizations.of( context, )! - .terms_conditions, style: TextStyle( + .terms_conditions, + style: TextStyle( color: Color(0xFF985400), // decoration: TextDecoration.underline, fontWeight: FontWeight @@ -671,16 +722,20 @@ class _ProfileScreenState extends State { TextSpan( text: AppLocalizations.of( context, - )!.t_and, - style: TextStyle(color: Color(0xFF898C81)), + )! + .t_and, + style: TextStyle(color: Color(0xFF898C81)), ), TextSpan( text: AppLocalizations.of( context, - )!.privacy_policy, style: TextStyle( + )! + .privacy_policy, + style: TextStyle( color: Color(0xFF985400), // decoration: TextDecoration.underline, - fontWeight: FontWeight.w600, // Makes the text bold + fontWeight: FontWeight + .w600, // Makes the text bold decorationColor: Color(0xFF985400), decorationThickness: 1, ), @@ -734,8 +789,7 @@ class _ProfileScreenState extends State { context.go('/createNewPw/$userId/$email'); }, child: Text( - AppLocalizations.of(context)! - .change_password, + AppLocalizations.of(context)!.change_password, style: TextStyle( color: Color(0xFF648CBA), fontSize: 14, diff --git a/lib/presentation/components/dialogs.dart b/lib/presentation/components/dialogs.dart index 7930de91..742af874 100644 --- a/lib/presentation/components/dialogs.dart +++ b/lib/presentation/components/dialogs.dart @@ -11,7 +11,7 @@ extension Dialogs on BuildContext { context: this, builder: (loaderContext) { if (!ctxWaiter.isCompleted) ctxWaiter.complete(loaderContext); - return const Dialog( + return Dialog( child: LinearProgressIndicator(), ); }, @@ -111,6 +111,18 @@ extension Dialogs on BuildContext { this, rootNavigator: true, ).pop, + style: TextButton.styleFrom( + // backgroundColor: Colors.white, // Background color + foregroundColor: Color(0xFF92722A), // Font (text) color + side: BorderSide( + color: Color(0xFF92722A)), // Border outline color + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(8), // Optional: Rounded corners + ), + padding: EdgeInsets.symmetric( + horizontal: 16, vertical: 12), // Optional: Padding + ), child: const Text('Return'), ), if (extraAction != null) extraAction, diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index 9f956b3d..8b82173f 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -698,19 +698,31 @@ class LoginRoute extends HookConsumerWidget { showDialog( context: context, builder: (context) => AlertDialog( - title: Text("Exit App"), - content: Text("Are you sure you want to exit?"), + title: Text( context.translate( + 'Exit App', + 'الخروج من التطبيق', + ),), + content: Text( context.translate( + 'Are you sure you want to exit?', + 'هل أنت متأكد أنك تريد الخروج؟', + ),), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), // Close dialog - child: Text("Cancel"), + child: Text( context.translate( + 'Cancel', + 'إلغاء', + ),), ), TextButton( onPressed: () => SystemNavigator.pop(), // Exit the app - child: Text("Exit"), + child: Text( context.translate( + 'Exit', + 'خروج', + ),), ), ], ), ); } -} +} \ No newline at end of file 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 6d7b850e..b7760198 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 @@ -167,6 +167,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:uae_stat/domain/use_cases/language.dart'; +import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart'; @@ -183,17 +185,73 @@ class MyHomePage extends ConsumerStatefulWidget { } class _MyHomePageState extends ConsumerState { + final PAuthRepo _authRepo = PAuthRepo(); + + Future logout(BuildContext context) async { + final prefs = await SharedPreferences.getInstance(); + await _authRepo.logout(); + prefs.clear(); + context.go('/login'); // Redirect to login after logout + } + + void _showExitConfirmation(BuildContext context) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text( + context.translate( + 'Logout', + 'تسجيل الخروج', + ), + ), + content: Text( + context.translate( + 'Are you sure you want to logout?', + 'هل أنت متأكد أنك تريد تسجيل الخروج؟', + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), // Close dialog + child: Text( + context.translate( + 'Cancel', + 'إلغاء', + ), + ), + ), + TextButton( + onPressed: () => logout(context), // Exit the app + child: Text( + context.translate( + 'Logout', + 'تسجيل الخروج', + ), + ), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { 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')))), - body: EconomyStatsWidget(), + return PopScope( + canPop: false, // Allow back navigation only if not login screen + onPopInvokedWithResult: (didPop, result) { + if (didPop) return; + _showExitConfirmation(context); // Show exit confirmation dialog + }, + child: BaseScaffold( + title: Center( + child: SizedBox( + height: myheight / 5, + width: mywidth / 3, + child: Image(image: AssetImage('assets/logos/uae_stat.png')))), + body: EconomyStatsWidget(), + ), ); } } diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart index 395a8363..2cec7155 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/bookmark.dart @@ -62,9 +62,10 @@ class _BookMarkState extends ConsumerState { final filteredList = dataList.where((item) => item['isBookmark'] == true).toList(); return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/myhomepage'); + context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( title: Text('Bookmark'), 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 0e4b8d51..91d9e684 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -425,9 +425,10 @@ class _EditProfileState extends State { @override Widget build(BuildContext context) { return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/myhomepage'); + context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( title: Text( diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart b/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart index d102df56..5ea7e374 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/feedback.dart @@ -238,9 +238,10 @@ class _FeedbackFormState extends State final userName = GoRouterState.of(context).extra as String? ?? 'Guest User'; return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/myhomepage'); + context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( // title: Text("Feedback"), @@ -550,8 +551,8 @@ class _FeedbackFormState extends State style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), const SizedBox(height: 15), - Text( -AppLocalizations.of(context)!.feedback_message, + Text( + AppLocalizations.of(context)!.feedback_message, style: TextStyle(fontSize: 16, color: Color(0xFF898C81)), textAlign: TextAlign.center, ), @@ -602,9 +603,9 @@ AppLocalizations.of(context)!.feedback_message, // Icon(Icons.error, size: 80, color: Colors.red), const SizedBox(height: 20), - Text( - AppLocalizations.of(context)!.failed_to_sharefeedback, - style: TextStyle( + Text( + AppLocalizations.of(context)!.failed_to_sharefeedback, + style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Color(0xFF414042)), @@ -753,10 +754,9 @@ AppLocalizations.of(context)!.feedback_message, ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - AppLocalizations.of(context)!.formError, - // "Please correct the errors before submitting." - ) - ), + AppLocalizations.of(context)!.formError, + // "Please correct the errors before submitting." + )), ); return; } @@ -786,10 +786,10 @@ AppLocalizations.of(context)!.feedback_message, // await sendFeedbackEmail(feedbackData, createdTime); await _removeFeedbackText(); ScaffoldMessenger.of(context).showSnackBar( - SnackBar( + SnackBar( content: Text(AppLocalizations.of(context)!.feedback_submitted), ), - ); + ); setState(() { _isFeedbackSubmitted = true; _isFeedbackFailed = false; @@ -798,12 +798,11 @@ AppLocalizations.of(context)!.feedback_message, } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text( - // "Failed to submit feedback: $e" + SnackBar( + content: Text( + // "Failed to submit feedback: $e" AppLocalizations.of(context)!.feedback_failed(e.toString()), - ) - - ), + )), ); setState(() { _isFeedbackFailed = true; // Update state to show failure message 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 acea3a4d..a588779c 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart @@ -144,7 +144,8 @@ class _ManageUserRouterState extends State { TextSpan( text: newStatus, style: TextStyle( - fontWeight: FontWeight.bold, // Makes newStatus bold + fontWeight: + FontWeight.bold, // Makes newStatus bold fontSize: 18, color: Color(0xFF898C81), ), @@ -175,74 +176,77 @@ class _ManageUserRouterState extends State { children: [ SizedBox( width: 100, // Set the desired width - child: - TextButton( - onPressed: () { - Navigator.of(context) - .pop(); // Close dialog without changing status - }, - style: TextButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - 10.0), // Adjust the radius as needed + child: TextButton( + onPressed: () { + Navigator.of(context) + .pop(); // Close dialog without changing status + }, + style: TextButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 10.0), // Adjust the radius as needed + ), + side: BorderSide( + color: Color(0xFFAA8E83), // Set the outline color + width: 1, // Set the border width + ), ), - side: BorderSide( - color: Color(0xFFAA8E83), // Set the outline color - width: 1, // Set the border width + child: Text( + AppLocalizations.of(context)!.no, + style: TextStyle( + color: Color(0xFFAA8E83), + fontSize: 16, + ), ), ), - child: Text(AppLocalizations.of(context)!.no, - style: TextStyle(color: Color(0xFFAA8E83), - fontSize: 16, - ),), - ), ), SizedBox( width: 100, // Set the desired width - child: - TextButton( - onPressed: () async { - try { - // Update status in PocketBase - await _pb.collection('users').update( - user.id, // User's unique ID - body: { - 'status': newStatus, // Update status - 'verified': newStatus == 'Approved' ? true : false, - 'reviewed': true, - }, - ); + child: TextButton( + onPressed: () async { + try { + // Update status in PocketBase + await _pb.collection('users').update( + user.id, // User's unique ID + body: { + 'status': newStatus, // Update status + 'verified': newStatus == 'Approved' ? true : false, + 'reviewed': true, + }, + ); - // Update local state - // setState(() { - // user.status = newStatus; - // }); - fetchUnverifiedUsers(); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Status updated successfully!')), - ); - } catch (e) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Error updating status: $e')), - ); - } - Navigator.of(context).pop(); // Close dialog - }, - style: TextButton.styleFrom( - backgroundColor: Color(0xFFAA8E83), // Set background color - foregroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10.0), // Set text color + // Update local state + // setState(() { + // user.status = newStatus; + // }); + fetchUnverifiedUsers(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Status updated successfully!')), + ); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error updating status: $e')), + ); + } + Navigator.of(context).pop(); // Close dialog + }, + style: TextButton.styleFrom( + backgroundColor: + Color(0xFFAA8E83), // Set background color + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(10.0), // Set text color + ), + ), + child: Text( + // 'Yes', + AppLocalizations.of(context)!.yes, + style: TextStyle(color: Colors.white, fontSize: 16), ), ), - child: Text( - // 'Yes', - AppLocalizations.of(context)!.yes, - style: TextStyle(color: Colors.white, - fontSize: 16), - ), - ),), + ), ], ) ], @@ -262,9 +266,10 @@ class _ManageUserRouterState extends State { double myheight = MediaQuery.of(context).size.height; return PopScope( + canPop: false, // Allow back navigation only if not login screen onPopInvokedWithResult: (didPop, result) { if (didPop) return; - context.go('/myhomepage'); + context.go('/myhomepage'); // Show exit confirmation dialog }, child: BaseScaffold( // title: Text("Manage User"), @@ -285,185 +290,186 @@ class _ManageUserRouterState extends State { // ), // ), // onChanged: filterUsers, - // ), + // ), Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(30.0), - border: Border.all(width: 2, color: Color(0xFFAA8E83)), - ), - child: TextField( - decoration: InputDecoration( - hintText: AppLocalizations.of(context)!.search, - prefixIcon: Image.asset( - MiscIconAssetPath.search, - width: 20, - height: 20, - ), - // ,prefixIcon: Icon( - // Icons.search, - // color: Color(0xFFAA8E83), - // ), - border: InputBorder.none, - contentPadding: - EdgeInsets.symmetric(vertical: 15.0, horizontal: 20.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(30.0), + border: Border.all(width: 2, color: Color(0xFFAA8E83)), ), - onChanged: filterUsers, - ), - ), - SizedBox(height: myheight / 40), - filteredUserData.isEmpty - ? Center( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(height: myheight/5), - - // Icon(Icons.search, - // size: 60, color: Colors.grey), - Image.asset( - MiscIconAssetPath.group, - width: 60, - height: 60, - ), - - SizedBox(height: 15), - // Space between icon and text - Text( - "No results found", - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.grey[700], - ), - ), - - SizedBox(height: 12), // Space between texts - FittedBox( - child: Text( - "We couldn't find anything matching your search.", - style: TextStyle( - fontSize: 18, color: Color(0xFF898C81)), - textAlign: TextAlign.center, - ),), - ], - ), + child: TextField( + decoration: InputDecoration( + hintText: AppLocalizations.of(context)!.search, + prefixIcon: Image.asset( + MiscIconAssetPath.search, + width: 20, + height: 20, ), - ) - : SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: ConstrainedBox( - constraints: BoxConstraints( - minWidth: MediaQuery.of(context).size.width, + // ,prefixIcon: Icon( + // Icons.search, + // color: Color(0xFFAA8E83), + // ), + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric( + vertical: 15.0, horizontal: 20.0), ), - child: DataTable( - sortColumnIndex: _sortColumnIndex, - sortAscending: _isAscending, - columns: [ - DataColumn( - label: Text( - AppLocalizations.of(context)!.user_name, - ), - onSort: (columnIndex, ascending) { - _sort((user) => user.userName.toLowerCase(), - columnIndex, ascending); - }, - ), - DataColumn( - label: Text( - AppLocalizations.of(context)!.email_id, - ), - onSort: (columnIndex, ascending) { - _sort((user) => user.emailId.toLowerCase(), - columnIndex, ascending); - }, - ), - DataColumn( - label: Text( - AppLocalizations.of(context)!.reg_date, - ), - onSort: (columnIndex, ascending) { - _sort( - (user) => DateFormat('dd/MM/yyyy') - .parse(user.registrationDate), - columnIndex, - ascending, - ); - }, - ), - DataColumn( - label: Text( - AppLocalizations.of(context)!.status, - ), - onSort: (columnIndex, ascending) { - _sort((user) => user.status.toLowerCase(), - columnIndex, ascending); - }, - ), - ], - rows: filteredUserData.isEmpty - ? [ - DataRow( - cells: List.generate( - 4, // Ensure it matches the number of DataColumns - (index) => DataCell( - index == 0 - ? Text( - 'No results found', - style: TextStyle( - fontStyle: - FontStyle.italic), - ) - : const Text( - ''), // Empty cells for other columns - placeholder: true, - ), + onChanged: filterUsers, + ), + ), + SizedBox(height: myheight / 40), + filteredUserData.isEmpty + ? Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: myheight / 5), + + // Icon(Icons.search, + // size: 60, color: Colors.grey), + Image.asset( + MiscIconAssetPath.group, + width: 60, + height: 60, + ), + + SizedBox(height: 15), + // Space between icon and text + Text( + "No results found", + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.grey[700], ), ), - ] - : filteredUserData.map((user) { - return DataRow( - cells: [ - DataCell(Text(user.userName)), - DataCell(Text(user.emailId)), - DataCell(Text(user.registrationDate)), - DataCell( - DropdownButton( - value: user.status, - items: statusOptions.entries - .map((status) { - return DropdownMenuItem( - value: status.key, - child: Text( - status.value, - style: TextStyle( - color: getStatusColor( - status.key), - ), - ), - ); - }).toList(), - onChanged: (newStatus) { - print(user); - if (newStatus != null) { - _showConfirmationDialog( - user, newStatus); - } - }, + + SizedBox(height: 12), // Space between texts + FittedBox( + child: Text( + "We couldn't find anything matching your search.", + style: TextStyle( + fontSize: 18, color: Color(0xFF898C81)), + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ) + : SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: ConstrainedBox( + constraints: BoxConstraints( + minWidth: MediaQuery.of(context).size.width, + ), + child: DataTable( + sortColumnIndex: _sortColumnIndex, + sortAscending: _isAscending, + columns: [ + DataColumn( + label: Text( + AppLocalizations.of(context)!.user_name, + ), + onSort: (columnIndex, ascending) { + _sort((user) => user.userName.toLowerCase(), + columnIndex, ascending); + }, + ), + DataColumn( + label: Text( + AppLocalizations.of(context)!.email_id, + ), + onSort: (columnIndex, ascending) { + _sort((user) => user.emailId.toLowerCase(), + columnIndex, ascending); + }, + ), + DataColumn( + label: Text( + AppLocalizations.of(context)!.reg_date, + ), + onSort: (columnIndex, ascending) { + _sort( + (user) => DateFormat('dd/MM/yyyy') + .parse(user.registrationDate), + columnIndex, + ascending, + ); + }, + ), + DataColumn( + label: Text( + AppLocalizations.of(context)!.status, + ), + onSort: (columnIndex, ascending) { + _sort((user) => user.status.toLowerCase(), + columnIndex, ascending); + }, + ), + ], + rows: filteredUserData.isEmpty + ? [ + DataRow( + cells: List.generate( + 4, // Ensure it matches the number of DataColumns + (index) => DataCell( + index == 0 + ? Text( + 'No results found', + style: TextStyle( + fontStyle: + FontStyle.italic), + ) + : const Text( + ''), // Empty cells for other columns + placeholder: true, + ), + ), ), - ), - ], - ); - }).toList(), - ), - ), - ), + ] + : filteredUserData.map((user) { + return DataRow( + cells: [ + DataCell(Text(user.userName)), + DataCell(Text(user.emailId)), + DataCell(Text(user.registrationDate)), + DataCell( + DropdownButton( + value: user.status, + items: statusOptions.entries + .map((status) { + return DropdownMenuItem( + value: status.key, + child: Text( + status.value, + style: TextStyle( + color: getStatusColor( + status.key), + ), + ), + ); + }).toList(), + onChanged: (newStatus) { + print(user); + if (newStatus != null) { + _showConfirmationDialog( + user, newStatus); + } + }, + ), + ), + ], + ); + }).toList(), + ), + ), + ), ], + ), ), ), - ), ), ); } diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart index 65aaf812..1602c807 100755 --- a/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/user_guide/userguide.dart @@ -51,7 +51,7 @@ class _UserguideState extends State { dividerColor: Colors.grey[300], appbarColor: Colors.white, title: Padding( - padding:EdgeInsets.only(bottom:8.0), + padding:EdgeInsets.only(bottom:0.0), child: Text('User Guide'), ) , body: Container( diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 3faf6977..de8376b5 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -14,6 +14,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:uae_stat/config/injector.dart'; import 'package:uae_stat/domain/repos/t_auth_repo.dart'; +import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bottom_bar_asset_icon_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/drawer_asset_icon_path.dart'; @@ -296,7 +297,7 @@ class _BaseScaffoldState extends ConsumerState { backgroundColor: Colors.transparent, elevation: 0, ), - child: Text( + child: Text( // 'Skip', AppLocalizations.of(context)!.skip, style: TextStyle( @@ -431,7 +432,7 @@ class _BaseScaffoldState extends ConsumerState { backgroundColor: Colors.transparent, elevation: 0, ), - child: Text( + child: Text( // 'Skip', AppLocalizations.of(context)!.skip, style: TextStyle( @@ -489,7 +490,7 @@ class _BaseScaffoldState extends ConsumerState { backgroundColor: Colors.white, elevation: 0, ), - child: Text( + child: Text( AppLocalizations.of(context)!.got_it, style: TextStyle( color: Color(0xFF7DAFBC), @@ -602,18 +603,26 @@ class _BaseScaffoldState extends ConsumerState { } } - Future logout() async { + // Future logout() async { + // final prefs = await SharedPreferences.getInstance(); + // // setState(() { + // // isLoggedOut = true; + // // }); + // // prefs.clear(); + // await _repo.logout(); + // // state = const AsyncData(null); + // // _pb.authStore.clear(); + // // await _secureStorage.delete(key: "FlutterSecureStorage.session"); + // prefs.clear(); + // context.go('/login'); + // } + final PAuthRepo _authRepo = PAuthRepo(); + + Future logout(BuildContext context) async { final prefs = await SharedPreferences.getInstance(); - // setState(() { - // isLoggedOut = true; - // }); - // prefs.clear(); - await _repo.logout(); - // state = const AsyncData(null); - // _pb.authStore.clear(); - // await _secureStorage.delete(key: "FlutterSecureStorage.session"); + await _authRepo.logout(); prefs.clear(); - context.go('/login'); + context.go('/login'); // Redirect to login after logout } @override @@ -628,7 +637,7 @@ class _BaseScaffoldState extends ConsumerState { backgroundColor: Colors.white, appBar: AppBar( // title: widget.title, - title: Align( + title: Align( alignment: Alignment.centerLeft, // Aligns the title to the left child: widget.title, ), @@ -642,7 +651,8 @@ class _BaseScaffoldState extends ConsumerState { color: widget.dividerColor, // Line color height: 1, // Line thickness ), - ): null, + ) + : null, actions: widget.actions ?? [ // IconButton( @@ -675,7 +685,7 @@ class _BaseScaffoldState extends ConsumerState { ), ), Positioned( - top: 5, + top: 8, right: 10, child: Builder( builder: (BuildContext context) { @@ -694,177 +704,176 @@ class _BaseScaffoldState extends ConsumerState { ), ), drawer: Drawer( - backgroundColor: Colors.white, + backgroundColor: Colors.white, child: Column(children: [ - Expanded( - child: ListView( - - children: [ - DrawerHeader( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Row( + Expanded( + child: ListView( + children: [ + DrawerHeader( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SizedBox( - width: mywidth / 8, - child: Image( - image: AssetImage('assets/logos/fcsc.png'), + Row( + children: [ + SizedBox( + width: mywidth / 8, + child: Image( + image: AssetImage('assets/logos/fcsc.png'), + ), + ), + ], + ), + Divider(), + InkWell( + onTap: () { + if (userId != 'guest') context.go('/editProfile'); + }, + child: Row( + children: [ + SizedBox( + width: mywidth / 8, + height: mywidth / 8, + child: ClipOval( + child: _avatarUrl.isNotEmpty + ? Image( + image: NetworkImage(_avatarUrl), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ) + : Image( + image: AssetImage( + 'assets/edit_profile/profile.png', + ), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ), + ), + //child: Image(image: AssetImage('assets/edit_profile/profile.png')) + ), + SizedBox( + width: mywidth / 20, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text(userId ?? 'Loading user...'), // Display userId here + // Text('Mohammad@fcsc.com') + if (userId == "guest") ...[ + Text(userName ?? 'Guest User'), + ] else ...[ + Text(userName ?? 'Loading...'), + Text( + userEmail ?? 'Loading...', + style: TextStyle(fontSize: 12), + ), + ] + ], + ), + ], ), ), ], ), - Divider(), - InkWell( - onTap: () { - if (userId != 'guest') context.go('/editProfile'); - }, - child: Row( - children: [ - SizedBox( - width: mywidth / 8, - height: mywidth / 8, - child: ClipOval( - child: _avatarUrl.isNotEmpty - ? Image( - image: NetworkImage(_avatarUrl), - fit: BoxFit.cover, - width: double.infinity, - height: double.infinity, - ) - : Image( - image: AssetImage( - 'assets/edit_profile/profile.png', - ), - fit: BoxFit.cover, - width: double.infinity, - height: double.infinity, - ), - ), - //child: Image(image: AssetImage('assets/edit_profile/profile.png')) - ), - SizedBox( - width: mywidth / 20, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Text(userId ?? 'Loading user...'), // Display userId here - // Text('Mohammad@fcsc.com') - if (userId == "guest") ...[ - Text(userName ?? 'Guest User'), - ] else ...[ - Text(userName ?? 'Loading...'), - Text( - userEmail ?? 'Loading...', - style: TextStyle(fontSize: 12), - ), - ] - ], - ), - ], + ), + if (userId != 'guest') + ListTile( + leading: Image.asset( + DrawerAssetIconPath.feedback, + color: Colors.black, + width: 20, + height: 20, ), + // title: const Text('Feedback'), + title: Text(AppLocalizations.of(context)!.feedback_title), + onTap: () => context.go('/feedback', extra: userName), ), - ], - ), - ), - if (userId != 'guest') - ListTile( - leading: Image.asset( - DrawerAssetIconPath.feedback, - color: Colors.black, - width: 20, - height: 20, + if (role == 'admin') + ListTile( + leading: Image.asset( + DrawerAssetIconPath.manageUser, + color: Colors.black, + width: 20, + height: 20, + ), + // title: Text('Manage User'), + title: Text( + AppLocalizations.of(context)!.manage_user, + ), + onTap: () => context.go('/manageuser'), + ), + ListTile( + leading: Icon(Icons.bookmarks_outlined), + // title: const Text('Bookmark'), + title: Text( + AppLocalizations.of(context)!.bookmark_title, + ), + onTap: () => context.go('/bookmark'), ), - // title: const Text('Feedback'), - title: Text(AppLocalizations.of(context)!.feedback_title), - onTap: () => context.go('/feedback', extra: userName), - ), - if (role == 'admin') - ListTile( - leading: Image.asset( - DrawerAssetIconPath.manageUser, - color: Colors.black, - width: 20, - height: 20, + ListTile( + leading: Image.asset( + DrawerAssetIconPath.guide, + color: Colors.black, + width: 20, + height: 20, + ), + // title: const Text('User Guide'), + title: Text(AppLocalizations.of(context)!.guide_title), + onTap: () => context.go('/user-guide'), ), - // title: Text('Manage User'), - title: Text( - AppLocalizations.of(context)!.manage_user, - ), - onTap: () => context.go('/manageuser'), - ), - ListTile( - leading: Icon(Icons.bookmarks_outlined), - // title: const Text('Bookmark'), - title: Text( - AppLocalizations.of(context)!.bookmark_title, - ), - onTap: () => context.go('/bookmark'), + if (userId != 'guest') + ListTile( + leading: Icon(Icons.logout), + // title: const Text('Logout'), + title: Text(AppLocalizations.of(context)!.logout), + onTap: () => logout(context), + ), + if (userId == 'guest') + ListTile( + leading: Icon(Icons.login), + // title: const Text('Login'), + title: Text(AppLocalizations.of(context)!.login_title), + onTap: () => context.go('/login'), + ), + if (userId == 'guest') + ListTile( + leading: Icon(Icons.app_registration), + // title: const Text('Register'), + title: Text(AppLocalizations.of(context)!.register_title), + onTap: () => context.go('/register'), + ), + ], ), - ListTile( - leading: Image.asset( - DrawerAssetIconPath.guide, - color: Colors.black, - width: 20, - height: 20, - ), - // title: const Text('User Guide'), - title: Text(AppLocalizations.of(context)!.guide_title), - onTap: () => context.go('/user-guide'), + ), + Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: FutureBuilder( + future: _getAppVersion(), // Function to get the app version + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return Text( + 'Loading version...', + style: TextStyle(fontSize: 12, color: Colors.grey), + textAlign: TextAlign.center, + ); + } else if (snapshot.hasError) { + return Text( + 'Error fetching version', + style: TextStyle(fontSize: 12, color: Colors.red), + textAlign: TextAlign.center, + ); + } else { + return Text( + 'Version ${snapshot.data}', + style: TextStyle(fontSize: 12, color: Colors.grey), + textAlign: TextAlign.center, + ); + } + }, ), - if (userId != 'guest') - ListTile( - leading: Icon(Icons.logout), - // title: const Text('Logout'), - title: Text(AppLocalizations.of(context)!.logout), - onTap: () => logout(), - ), - if (userId == 'guest') - ListTile( - leading: Icon(Icons.login), - // title: const Text('Login'), - title: Text(AppLocalizations.of(context)!.login_title), - onTap: () => context.go('/login'), - ), - if (userId == 'guest') - ListTile( - leading: Icon(Icons.app_registration), - // title: const Text('Register'), - title: Text(AppLocalizations.of(context)!.register_title), - onTap: () => context.go('/register'), - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.only(bottom: 16.0), - child: FutureBuilder( - future: _getAppVersion(), // Function to get the app version - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return Text( - 'Loading version...', - style: TextStyle(fontSize: 12, color: Colors.grey), - textAlign: TextAlign.center, - ); - } else if (snapshot.hasError) { - return Text( - 'Error fetching version', - style: TextStyle(fontSize: 12, color: Colors.red), - textAlign: TextAlign.center, - ); - } else { - return Text( - 'Version ${snapshot.data}', - style: TextStyle(fontSize: 12, color: Colors.grey), - textAlign: TextAlign.center, - ); - } - }, - ), - ), - ])), + ), + ])), bottomNavigationBar: BottomNavigationBar( backgroundColor: Colors.white, currentIndex: _getSelectedIndex(currentRoute),