diff --git a/sigap-mobile/lib/src/features/auth/data/repositories/authentication_repository.dart b/sigap-mobile/lib/src/features/auth/data/repositories/authentication_repository.dart index 3a88d44..f8239b4 100644 --- a/sigap-mobile/lib/src/features/auth/data/repositories/authentication_repository.dart +++ b/sigap-mobile/lib/src/features/auth/data/repositories/authentication_repository.dart @@ -116,7 +116,7 @@ class AuthenticationRepository extends GetxController { } } catch (e) { Logger().e('Error in screenRedirect: $e'); - _navigateToRoute(AppRoutes.checkLocation); + _navigateToRoute(AppRoutes.signIn); } finally { _isRedirecting = false; Logger().d('Screen redirect completed'); diff --git a/sigap-mobile/lib/src/features/auth/presentasion/controllers/forgot-password/forgot_password_controller.dart b/sigap-mobile/lib/src/features/auth/presentasion/controllers/forgot-password/forgot_password_controller.dart index 6e73222..1706f51 100644 --- a/sigap-mobile/lib/src/features/auth/presentasion/controllers/forgot-password/forgot_password_controller.dart +++ b/sigap-mobile/lib/src/features/auth/presentasion/controllers/forgot-password/forgot_password_controller.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:sigap/src/features/auth/data/repositories/authentication_repository.dart'; +import 'package:sigap/src/shared/widgets/state_screeen/state_screen.dart'; +import 'package:sigap/src/utils/constants/image_strings.dart'; import 'package:sigap/src/utils/popups/loaders.dart'; import 'package:sigap/src/utils/validators/validation.dart'; @@ -45,9 +47,6 @@ class ForgotPasswordController extends GetxController { try { isLoading.value = true; - // Simulate API call - await Future.delayed(const Duration(seconds: 2)); - await AuthenticationRepository.instance.sendResetPasswordForEmail( emailController.text, ); @@ -58,6 +57,19 @@ class ForgotPasswordController extends GetxController { title: 'Success', message: 'Reset password email sent successfully.', ); + + Get.off( + () => StateScreen( + title: 'Check Your Email', + subtitle: 'Please check your email for the reset link.', + image: TImages.customerSupport, + isSvg: true, + primaryButtonTitle: 'Go Back', + showButton: true, + + onPressed: () => Get.back(), + ), + ); } catch (e) { Get.snackbar( 'Error', diff --git a/sigap-mobile/lib/src/features/auth/presentasion/controllers/signin/signin_controller.dart b/sigap-mobile/lib/src/features/auth/presentasion/controllers/signin/signin_controller.dart index e3bfc6c..172b215 100644 --- a/sigap-mobile/lib/src/features/auth/presentasion/controllers/signin/signin_controller.dart +++ b/sigap-mobile/lib/src/features/auth/presentasion/controllers/signin/signin_controller.dart @@ -7,44 +7,44 @@ import 'package:sigap/src/utils/popups/loaders.dart'; class SignInController extends GetxController { static SignInController get instance => Get.find(); - + final _logger = Logger(); final _authRepo = Get.find(); - + // Form controllers final email = TextEditingController(); final password = TextEditingController(); - + // Form error messages final RxString emailError = RxString(''); final RxString passwordError = RxString(''); - + // States final RxBool isLoading = RxBool(false); final RxBool isPasswordVisible = RxBool(false); - + @override void onClose() { email.dispose(); password.dispose(); super.onClose(); } - + // Toggle password visibility void togglePasswordVisibility() { isPasswordVisible.value = !isPasswordVisible.value; } - + // Navigate to forgot password screen void goToForgotPassword() { Get.toNamed(AppRoutes.forgotPassword); } - + // Navigate to sign up screen void goToSignUp() { Get.toNamed(AppRoutes.roleSelection); } - + // Clear error messages void clearErrors() { emailError.value = ''; @@ -55,7 +55,7 @@ class SignInController extends GetxController { Future signIn(GlobalKey formKey) async { // Clear previous errors clearErrors(); - + // Validate form final isValid = formKey.currentState?.validate() ?? false; if (!isValid) return; @@ -64,20 +64,19 @@ class SignInController extends GetxController { isLoading.value = true; // Attempt to sign in - final signInResult = await _authRepo.loginWithEmailPassword( + await _authRepo.loginWithEmailPassword( email: email.text.trim(), password: password.text.trim(), ); - + // Handle result - _logger.i('Sign in successful: $signInResult'); - + // _logger.i('Sign in successful: $signInResult'); + // Redirect based on user's profile status _authRepo.screenRedirect(); - } catch (e) { isLoading.value = false; - + // Handle specific errors if (e.toString().contains('user-not-found')) { emailError.value = 'No user found with this email'; @@ -89,36 +88,110 @@ class SignInController extends GetxController { // Show general error TLoaders.errorSnackBar(title: 'Sign In Failed', message: e.toString()); } - + _logger.e('Sign in error: $e'); } finally { isLoading.value = false; } } - + // Sign in with Google Future googleSignIn() async { try { isLoading.value = true; - + // Attempt to sign in with Google await _authRepo.signInWithGoogle(); - + // Redirect based on user's profile status _authRepo.screenRedirect(); - } catch (e) { isLoading.value = false; - + // Show error TLoaders.errorSnackBar( title: 'Google Sign In Failed', message: e.toString(), ); - + _logger.e('Google sign in error: $e'); } finally { isLoading.value = false; } } + + // Sign in with github + Future githubSignIn() async { + try { + isLoading.value = true; + + // Attempt to sign in with GitHub + await _authRepo.signInWithGithub(); + + // Redirect based on user's profile status + _authRepo.screenRedirect(); + } catch (e) { + isLoading.value = false; + + // Show error + TLoaders.errorSnackBar( + title: 'GitHub Sign In Failed', + message: e.toString(), + ); + + _logger.e('GitHub sign in error: $e'); + } finally { + isLoading.value = false; + } + } + + // Sign in with Facebook + Future facebookSignIn() async { + try { + isLoading.value = true; + + // Attempt to sign in with Facebook + await _authRepo.signInWithFacebook(); + + // Redirect based on user's profile status + _authRepo.screenRedirect(); + } catch (e) { + isLoading.value = false; + + // Show error + TLoaders.errorSnackBar( + title: 'Facebook Sign In Failed', + message: e.toString(), + ); + + _logger.e('Facebook sign in error: $e'); + } finally { + isLoading.value = false; + } + } + + // Sign in with Apple + Future appleSignIn() async { + try { + isLoading.value = true; + + // Attempt to sign in with Apple + await _authRepo.signInWithApple(); + + // Redirect based on user's profile status + _authRepo.screenRedirect(); + } catch (e) { + isLoading.value = false; + + // Show error + TLoaders.errorSnackBar( + title: 'Apple Sign In Failed', + message: e.toString(), + ); + + _logger.e('Apple sign in error: $e'); + } finally { + isLoading.value = false; + } + } } diff --git a/sigap-mobile/lib/src/features/auth/presentasion/pages/forgot-password/forgot_password.dart b/sigap-mobile/lib/src/features/auth/presentasion/pages/forgot-password/forgot_password.dart index 00aa0cb..6579555 100644 --- a/sigap-mobile/lib/src/features/auth/presentasion/pages/forgot-password/forgot_password.dart +++ b/sigap-mobile/lib/src/features/auth/presentasion/pages/forgot-password/forgot_password.dart @@ -1,11 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:sigap/src/features/auth/presentasion/controllers/forgot-password/forgot_password_controller.dart'; import 'package:sigap/src/features/auth/presentasion/widgets/auth_button.dart'; import 'package:sigap/src/features/auth/presentasion/widgets/auth_header.dart'; import 'package:sigap/src/shared/widgets/text/custom_text_field.dart'; import 'package:sigap/src/utils/constants/colors.dart'; +import 'package:sigap/src/utils/constants/image_strings.dart'; +import 'package:sigap/src/utils/constants/sizes.dart'; +import 'package:sigap/src/utils/helpers/helper_functions.dart'; class ForgotPasswordScreen extends StatelessWidget { const ForgotPasswordScreen({super.key}); @@ -15,6 +19,8 @@ class ForgotPasswordScreen extends StatelessWidget { // Get the controller final controller = Get.find(); + final isDarkMode = THelperFunctions.isDarkMode(context); + // Set system overlay style SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( @@ -24,26 +30,29 @@ class ForgotPasswordScreen extends StatelessWidget { ); return Scaffold( - backgroundColor: TColors.light, appBar: AppBar( - backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( - icon: Icon(Icons.arrow_back, color: TColors.textPrimary), + icon: Icon( + Icons.arrow_back, + color: isDarkMode ? TColors.accent : TColors.primary, + ), onPressed: controller.goBack, ), ), body: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(24.0), - child: Obx( - () => Form( - key: controller.formKey, - child: - controller.isEmailSent.value - ? _buildSuccessView(controller) - : _buildFormView(controller), + child: Center( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(TSizes.defaultSpace), + child: Obx( + () => Form( + key: controller.formKey, + child: + controller.isEmailSent.value + ? _buildSuccessView(controller) + : _buildFormView(controller, context), + ), ), ), ), @@ -52,16 +61,28 @@ class ForgotPasswordScreen extends StatelessWidget { ); } - Widget _buildFormView(ForgotPasswordController controller) { + Widget _buildFormView( + ForgotPasswordController controller, + BuildContext? context, + ) { + final isDark = THelperFunctions.isDarkMode(context!); return Column( - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - // Header + // Logo centered + SvgPicture.asset(TImages.lightAppBgLogo, height: 100, width: 100), + const SizedBox(height: 16), + + // Header centered const AuthHeader( + crossAxisAlignment: CrossAxisAlignment.center, title: 'Forgot Password', subtitle: 'Enter your email to reset your password', ), + const SizedBox(height: 24), + // Email field Obx( () => CustomTextField( @@ -70,6 +91,12 @@ class ForgotPasswordScreen extends StatelessWidget { validator: controller.validateEmail, keyboardType: TextInputType.emailAddress, errorText: controller.emailError.value, + hintText: 'enter your email', + prefixIcon: Icon( + Icons.email_outlined, + size: 20, + color: isDark ? TColors.accent : TColors.primary, + ), ), ), @@ -89,8 +116,11 @@ class ForgotPasswordScreen extends StatelessWidget { Widget _buildSuccessView(ForgotPasswordController controller) { return Column( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ + // Logo centered + SvgPicture.asset(TImages.lightAppBgLogo, height: 100, width: 100), const SizedBox(height: 32), // Success icon diff --git a/sigap-mobile/lib/src/features/auth/presentasion/pages/signin/signin_screen.dart b/sigap-mobile/lib/src/features/auth/presentasion/pages/signin/signin_screen.dart index 9b3b719..2e3942c 100644 --- a/sigap-mobile/lib/src/features/auth/presentasion/pages/signin/signin_screen.dart +++ b/sigap-mobile/lib/src/features/auth/presentasion/pages/signin/signin_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_tabler_icons/flutter_tabler_icons.dart'; import 'package:get/get.dart'; import 'package:sigap/src/features/auth/presentasion/controllers/signin/signin_controller.dart'; @@ -8,6 +9,7 @@ import 'package:sigap/src/features/auth/presentasion/widgets/auth_header.dart'; import 'package:sigap/src/features/auth/presentasion/widgets/password_field.dart'; import 'package:sigap/src/features/auth/presentasion/widgets/social_button.dart'; import 'package:sigap/src/shared/widgets/text/custom_text_field.dart'; +import 'package:sigap/src/utils/constants/image_strings.dart'; // Added for logo image import 'package:sigap/src/utils/helpers/helper_functions.dart'; import 'package:sigap/src/utils/validators/validation.dart'; @@ -26,116 +28,173 @@ class SignInScreen extends StatelessWidget { final isDarkMode = THelperFunctions.isDarkMode(context); return Scaffold( - // Use dynamic background color from theme body: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(24.0), - child: Form( - key: formKey, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 16), - - // Header - pass isDarkMode to AuthHeader if needed - const AuthHeader( - title: 'Welcome Back', - subtitle: 'Sign in to your account to continue', - ), - - // Email field - Obx( - () => CustomTextField( - label: 'Email', - controller: controller.email, - validator: TValidators.validateEmail, - keyboardType: TextInputType.emailAddress, - errorText: controller.emailError.value, - textInputAction: TextInputAction.next, + child: Center( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Form( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Logo centered at the top + SvgPicture.asset( + TImages.lightAppBgLogo, + height: 100, + width: 100, ), - ), + const SizedBox(height: 16), - // Password field - Obx( - () => PasswordField( - label: 'Password', - controller: controller.password, - validator: TValidators.validatePassword, - isVisible: controller.isPasswordVisible, - errorText: controller.passwordError.value, - onToggleVisibility: controller.togglePasswordVisibility, + // Header centered + const AuthHeader( + crossAxisAlignment: CrossAxisAlignment.center, + title: 'Welcome Back', + subtitle: 'Sign in to your account to continue', ), - ), - // Forgot password - Align( - alignment: Alignment.centerRight, - child: TextButton( - onPressed: controller.goToForgotPassword, - child: Text( - 'Forgot Password?', - style: TextStyle( - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.w500, - ), + const SizedBox(height: 24), + + // Email field with icon + Obx( + () => CustomTextField( + label: 'Email', + controller: controller.email, + validator: TValidators.validateEmail, + keyboardType: TextInputType.emailAddress, + errorText: controller.emailError.value, + textInputAction: TextInputAction.next, + prefixIcon: const Icon(TablerIcons.mail, size: 20), ), ), - ), - const SizedBox(height: 16), - - // Sign in button - Obx( - () => AuthButton( - text: 'Sign In', - onPressed: () => controller.signIn(formKey), - isLoading: controller.isLoading.value, - ), - ), - - const SizedBox(height: 24), - - // Or divider - const AuthDivider(text: 'OR'), - - const SizedBox(height: 24), - - // Social sign in buttons - SocialButton( - text: 'Continue with Google', - icon: Icon( - TablerIcons.brand_google, - color: Colors.white, - size: 20, - ), - onPressed: () => controller.googleSignIn(), - ), - - const SizedBox(height: 16), - - // Don't have an account - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Don\'t have an account?', - // Use theme color for text - style: TextStyle(color: Theme.of(context).hintColor), + // Password field with icon + Obx( + () => PasswordField( + label: 'Password', + controller: controller.password, + validator: TValidators.validatePassword, + isVisible: controller.isPasswordVisible, + errorText: controller.passwordError.value, + onToggleVisibility: controller.togglePasswordVisibility, + prefixIcon: const Icon(TablerIcons.lock, size: 20), ), - TextButton( - onPressed: controller.goToSignUp, + ), + + // Forgot password + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: controller.goToForgotPassword, child: Text( - 'Sign Up', + 'Forgot Password?', style: TextStyle( color: Theme.of(context).primaryColor, fontWeight: FontWeight.w500, ), ), ), - ], - ), - ], + ), + + const SizedBox(height: 16), + + // Sign in button + Obx( + () => AuthButton( + text: 'Sign In', + onPressed: () => controller.signIn(formKey), + isLoading: controller.isLoading.value, + ), + ), + + const SizedBox(height: 24), + + // Or divider + const AuthDivider(text: 'OR'), + + const SizedBox(height: 24), + + // Social sign in buttons - Row of social icons + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + // Google Sign In + Expanded( + child: SocialButton( + shapeType: SocialButtonShapeType.circular, + icon: const Icon( + TablerIcons.brand_google, + color: Colors.white, + size: 20, + ), + backgroundColor: const Color(0xFFDB4437), + foregroundColor: Colors.white, + onPressed: () => controller.googleSignIn(), + ), + ), + + const SizedBox(width: 0), + + // GitHub Sign In + Expanded( + child: SocialButton( + shapeType: SocialButtonShapeType.circular, + icon: const Icon( + TablerIcons.brand_apple, + color: Colors.white, + size: 20, + ), + backgroundColor: const Color(0xFF333333), + foregroundColor: Colors.white, + onPressed: () => controller.appleSignIn(), + ), + ), + + const SizedBox(width: 0), + + // Facebook Sign In + Expanded( + child: SocialButton( + shapeType: SocialButtonShapeType.circular, + icon: const Icon( + TablerIcons.brand_facebook, + color: Colors.white, + size: 20, + ), + backgroundColor: const Color(0xFF1877F2), + foregroundColor: Colors.white, + onPressed: () => controller.facebookSignIn(), + ), + ), + ], + ), + + const SizedBox(height: 16), + + // Don't have an account + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Don\'t have an account?', + // Use theme color for text + style: TextStyle(color: Theme.of(context).hintColor), + ), + TextButton( + onPressed: controller.goToSignUp, + child: Text( + 'Sign Up', + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ], + ), ), ), ), diff --git a/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_button.dart b/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_button.dart index 640c1db..291334e 100644 --- a/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_button.dart +++ b/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_button.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:sigap/src/utils/constants/colors.dart'; import 'package:sigap/src/utils/constants/sizes.dart'; +import 'package:sigap/src/utils/helpers/helper_functions.dart'; class AuthButton extends StatelessWidget { final String text; @@ -19,6 +21,7 @@ class AuthButton extends StatelessWidget { @override Widget build(BuildContext context) { + final isDark = THelperFunctions.isDarkMode(context); return SizedBox( width: double.infinity, height: 55, @@ -26,7 +29,8 @@ class AuthButton extends StatelessWidget { onPressed: isLoading ? null : onPressed, style: ElevatedButton.styleFrom( backgroundColor: backgroundColor ?? Theme.of(context).primaryColor, - foregroundColor: textColor ?? Theme.of(context).colorScheme.onPrimary, + foregroundColor: + textColor ?? (isDark ? TColors.primary : TColors.accent), elevation: 1, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(TSizes.buttonRadius), diff --git a/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_header.dart b/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_header.dart index fc53be0..fc0785f 100644 --- a/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_header.dart +++ b/sigap-mobile/lib/src/features/auth/presentasion/widgets/auth_header.dart @@ -5,15 +5,21 @@ import 'package:sigap/src/utils/helpers/helper_functions.dart'; class AuthHeader extends StatelessWidget { final String title; final String subtitle; + final CrossAxisAlignment crossAxisAlignment; - const AuthHeader({super.key, required this.title, required this.subtitle}); + const AuthHeader({ + super.key, + required this.title, + required this.subtitle, + this.crossAxisAlignment = CrossAxisAlignment.start, + }); @override Widget build(BuildContext context) { final dark = THelperFunctions.isDarkMode(context); return Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: crossAxisAlignment, children: [ Text( title, diff --git a/sigap-mobile/lib/src/features/auth/presentasion/widgets/social_button.dart b/sigap-mobile/lib/src/features/auth/presentasion/widgets/social_button.dart index acbff18..75e04b4 100644 --- a/sigap-mobile/lib/src/features/auth/presentasion/widgets/social_button.dart +++ b/sigap-mobile/lib/src/features/auth/presentasion/widgets/social_button.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; import 'package:sigap/src/utils/constants/sizes.dart'; +enum SocialButtonShapeType { defaultShape, rounded, circular } + class SocialButton extends StatelessWidget { - final String text; + final String? text; final Icon? icon; final String? iconImage; final double? iconImageWidth; @@ -12,10 +14,11 @@ class SocialButton extends StatelessWidget { final Color? foregroundColor; final Color? borderColor; final bool isVisible; + final SocialButtonShapeType shapeType; const SocialButton({ super.key, - required this.text, + this.text, this.icon, this.iconImage, this.iconImageWidth, @@ -25,53 +28,81 @@ class SocialButton extends StatelessWidget { this.foregroundColor, this.borderColor, this.isVisible = true, + this.shapeType = SocialButtonShapeType.defaultShape, }); @override Widget build(BuildContext context) { if (!isVisible) return const SizedBox.shrink(); + OutlinedBorder shape; + EdgeInsetsGeometry padding; + + switch (shapeType) { + case SocialButtonShapeType.rounded: + shape = RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)); + padding = const EdgeInsets.symmetric( + vertical: TSizes.md, + horizontal: TSizes.md, + ); + break; + case SocialButtonShapeType.circular: + shape = const CircleBorder(); + padding = const EdgeInsets.all(0); + break; + default: + shape = RoundedRectangleBorder( + borderRadius: BorderRadius.circular(TSizes.buttonRadius), + ); + padding = const EdgeInsets.symmetric( + vertical: TSizes.md, + horizontal: TSizes.md, + ); + } + + Widget iconWidget = + iconImage == null + ? icon ?? const SizedBox.shrink() + : Image.asset( + iconImage!, + width: iconImageWidth, + height: iconImageHeight, + ); + + Widget child; + if (text == null || text!.isEmpty) { + child = iconWidget; + } else { + child = Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 24, width: 24, child: iconWidget), + const SizedBox(width: TSizes.md), + Text( + text!, + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + color: foregroundColor ?? Colors.black, + fontWeight: FontWeight.w500, + ), + ), + ], + ); + } + return SizedBox( - width: double.infinity, + width: shapeType == SocialButtonShapeType.circular ? 48 : double.infinity, + height: shapeType == SocialButtonShapeType.circular ? 48 : null, child: OutlinedButton( onPressed: onPressed, style: OutlinedButton.styleFrom( backgroundColor: backgroundColor ?? Colors.white, foregroundColor: foregroundColor ?? Colors.black, side: BorderSide(color: borderColor ?? Colors.grey.shade300), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(TSizes.buttonRadius), - ), - padding: const EdgeInsets.symmetric( - vertical: TSizes.md, - horizontal: TSizes.md, - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - height: 24, - width: 24, - child: - iconImage == null - ? icon - : Image.asset( - iconImage!, - width: iconImageWidth, - height: iconImageHeight, - ), - ), - const SizedBox(width: TSizes.md), - Text( - text, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - color: foregroundColor ?? Colors.black, - fontWeight: FontWeight.w500, - ), - ), - ], + shape: shape, + padding: padding, ), + child: child, ), ); } diff --git a/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/check_location_controller.dart b/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/check_location_controller.dart index 20fcfdd..85dbca0 100644 --- a/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/check_location_controller.dart +++ b/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/check_location_controller.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:get_storage/get_storage.dart'; import 'package:sigap/src/cores/services/location_service.dart'; import 'package:sigap/src/features/onboarding/presentasion/pages/role-selection/role_signup_pageview.dart'; import 'package:sigap/src/utils/constants/image_strings.dart'; @@ -11,6 +12,8 @@ class CheckLocationController extends GetxController final VoidCallback? onSuccess; final LocationService _locationService = LocationService.instance; + final storage = GetStorage(); + // Reactive variables final RxInt currentPage = 0.obs; final RxBool isLoading = false.obs; @@ -146,6 +149,8 @@ class CheckLocationController extends GetxController // Navigate to communication slide before zooming _navigateToCommunicationSlide(); + storage.write('isFirstTime', false); + // Give time to see the success message before animating await Future.delayed(Duration(milliseconds: 800)); animController diff --git a/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/onboarding_controller.dart b/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/onboarding_controller.dart index 3f1487e..728e7d2 100644 --- a/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/onboarding_controller.dart +++ b/sigap-mobile/lib/src/features/onboarding/presentasion/controllers/onboarding_controller.dart @@ -81,16 +81,16 @@ class OnboardingController extends GetxController } } - // Method to skip to welcome screen - void skipToWelcomeScreen() { + // Method to skip to check location screen + void skipToCheckLocation() { skipOnboarding(); } - // Method to navigate to welcome screen + // Method to navigate to check location screen void skipOnboarding() { // Mark onboarding as completed in storage - storage.write('isFirstTime', true); - Get.offAllNamed(AppRoutes.welcome); + storage.write('isFirstTime', false); + Get.offAllNamed(AppRoutes.checkLocation); } // Method to check location validity and proceed with auth flow @@ -136,7 +136,7 @@ class OnboardingController extends GetxController } void goToSignIn() { - storage.write('isFirstTime', true); + storage.write('isFirstTime', false); Get.offAllNamed(AppRoutes.signIn); } diff --git a/sigap-mobile/lib/src/utils/popups/loaders.dart b/sigap-mobile/lib/src/utils/popups/loaders.dart index be2db3f..754a90c 100644 --- a/sigap-mobile/lib/src/utils/popups/loaders.dart +++ b/sigap-mobile/lib/src/utils/popups/loaders.dart @@ -47,7 +47,7 @@ class TLoaders { isDismissible: true, shouldIconPulse: true, colorText: Colors.white, - backgroundColor: TColors.primary, + backgroundColor: TColors.success, snackPosition: SnackPosition.TOP, duration: Duration(seconds: duration), margin: const EdgeInsets.all(10),