import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:get/get.dart'; import 'package:taxglide/consts/app_asstes.dart'; import 'package:taxglide/consts/app_colors.dart'; import 'package:taxglide/consts/comman_button.dart'; import 'package:taxglide/consts/comman_container_auth.dart'; import 'package:taxglide/consts/comman_textformfileds.dart'; import 'package:taxglide/consts/comman_popup.dart'; import 'package:taxglide/consts/responsive_helper.dart'; import 'package:taxglide/consts/validation_popup.dart'; import 'package:taxglide/controller/api_contoller.dart'; import 'package:taxglide/router/consts_routers.dart'; import 'package:taxglide/consts/app_style.dart'; class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override ConsumerState createState() => _LoginScreenState(); } class _LoginScreenState extends ConsumerState { final TextEditingController _mobileController = TextEditingController(); final ValidationPopup _validationPopup = ValidationPopup(); @override void initState() { super.initState(); final args = Get.arguments; if (args != null && args is Map) { final mobile = args['mobile'] ?? ''; if (mobile.isNotEmpty) { _mobileController.text = mobile; } } } @override void dispose() { _mobileController.dispose(); super.dispose(); } Future _handleLogin() async { final mobile = _mobileController.text.trim(); if (!_validationPopup.validateMobileNumber(context, mobile)) { return; } await ref.read(loginProvider.notifier).login(mobile); final state = ref.read(loginProvider); state.when( data: (data) { if (data['success'] == true) { Get.toNamed(ConstRouters.otp, arguments: {'mobile': mobile}); _validationPopup.showSuccessMessage( context, "OTP sent successfully!", ); } else if (data['error'] != null) { _validationPopup.showErrorMessage(context, data['error'].toString()); } }, loading: () {}, error: (err, _) { _validationPopup.showErrorMessage(context, "Error: $err"); }, ); } @override Widget build(BuildContext context) { final loginState = ref.watch(loginProvider); final policyAsync = ref.watch(policyProvider); final termsAsync = ref.watch(termsProvider); // Initialize responsive utils final r = ResponsiveUtils(context); // Responsive values final logoWidth = r.getValue( mobile: 120, tablet: 141, desktop: 160, ); final logoHeight = r.getValue( mobile: 85, tablet: 100, desktop: 115, ); final titleFontSize = r.fontSize(mobile: 26, tablet: 32, desktop: 36); final subtitleFontSize = r.fontSize(mobile: 13, tablet: 14, desktop: 15); final termsFontSize = r.fontSize(mobile: 10.5, tablet: 11.34, desktop: 12); final signupFontSize = r.fontSize(mobile: 13, tablet: 14, desktop: 15); final otherLoginFontSize = r.fontSize(mobile: 12, tablet: 13, desktop: 14); final spacingXS = r.spacing(mobile: 10, tablet: 15, desktop: 18); final spacingSM = r.spacing(mobile: 15, tablet: 20, desktop: 24); final spacingMD = r.spacing(mobile: 20, tablet: 22, desktop: 26); final spacingLG = r.spacing(mobile: 20, tablet: 22, desktop: 28); return PopScope( canPop: true, onPopInvokedWithResult: (didPop, result) { // Handle custom behavior here if needed in the future }, child: Scaffold( resizeToAvoidBottomInset: true, body: Container( width: double.infinity, height: double.infinity, decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Color(0xFFFFF8F0), Color(0xFFEBC894), Color(0xFFE8DAF2), Color(0xFFB49EF4), ], stops: [0.0, 0.3, 0.6, 1.0], ), ), child: SingleChildScrollView( child: ConstrainedBox( constraints: BoxConstraints(minHeight: r.screenHeight), child: IntrinsicHeight( child: Center( child: CommonContainerAuth( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ // Logo Image.asset( AppAssets.taxgildelogoauth, width: logoWidth, height: logoHeight, ), SizedBox(height: spacingSM), // Title Text( "Login", style: AppTextStyles.semiBold.copyWith( fontSize: titleFontSize, color: AppColors.authheading, ), ), SizedBox(height: spacingSM), // Subtitle Text( "Enter your Mobile Number", textAlign: TextAlign.center, style: AppTextStyles.semiBold.copyWith( fontSize: subtitleFontSize, color: AppColors.authleading, ), ), SizedBox(height: spacingLG), // Mobile TextField CommanTextFormField( controller: _mobileController, hintText: 'Enter your Mobile Number', keyboardType: TextInputType.phone, prefixIcon: Icons.mobile_screen_share, ), SizedBox(height: spacingLG), // Terms and Policy Text.rich( TextSpan( text: "By signing up, you agree to the ", style: AppTextStyles.medium.copyWith( fontSize: termsFontSize, color: AppColors.authleading, ), children: [ TextSpan( text: "Terms of Service ", style: AppTextStyles.bold.copyWith( fontSize: termsFontSize, color: AppColors.authtermsandcondition, ), recognizer: TapGestureRecognizer() ..onTap = () { termsAsync.when( data: (terms) { CommonInfoPopup.show( context: context, title: terms.data?.title ?? "Terms of Service", content: terms.data?.content ?? "No terms found.", ); }, loading: () { _validationPopup.showErrorMessage( context, "Loading Terms...", ); }, error: (err, _) { _validationPopup.showErrorMessage( context, "Failed to load Terms", ); }, ); }, ), const TextSpan(text: "and "), TextSpan( text: "Data Processing Agreement", style: TextStyle( fontWeight: FontWeight.w700, fontSize: termsFontSize, color: AppColors.authtermsandcondition, ), recognizer: TapGestureRecognizer() ..onTap = () { policyAsync.when( data: (policy) { CommonInfoPopup.show( context: context, title: policy.data?.title ?? "Data Processing Agreement", content: policy.data?.content ?? "No policy found.", ); }, loading: () { _validationPopup.showErrorMessage( context, "Loading Policy...", ); }, error: (err, _) { _validationPopup.showErrorMessage( context, "Failed to load Policy", ); }, ); }, ), ], ), textAlign: TextAlign.center, ), SizedBox(height: spacingSM), Text("Or",style: AppTextStyles.medium.copyWith( fontSize: spacingSM, color: AppColors.authleading, ),), SizedBox(height: spacingSM), // Sign up Text.rich( TextSpan( text: "Didn't Have account? ", style: AppTextStyles.bold.copyWith( fontSize: signupFontSize, color: AppColors.black, ), children: [ TextSpan( text: "Sign Up", style: AppTextStyles.bold.copyWith( fontSize: signupFontSize, color: AppColors.authsignup, ), recognizer: TapGestureRecognizer() ..onTap = () { Get.offNamed(ConstRouters.signup); }, ), ], ), ), SizedBox(height: spacingLG), // Login Button loginState.isLoading ? const CircularProgressIndicator() : CommanButton( text: "Login", onPressed: _handleLogin, ), SizedBox(height: spacingMD), Text( "Other Login", textAlign: TextAlign.center, style: AppTextStyles.semiBold.copyWith( fontSize: otherLoginFontSize, height: 1.8, letterSpacing: 0.13, color: AppColors.authleading, ), ), SizedBox(height: spacingXS), Text.rich( TextSpan( text: "Staff Login? ", style: AppTextStyles.bold.copyWith( fontSize: signupFontSize, color: AppColors.black, ), children: [ TextSpan( text: "Click Here", style: AppTextStyles.bold.copyWith( fontSize: signupFontSize, color: AppColors.authsignup, ), recognizer: TapGestureRecognizer() ..onTap = () { Get.offNamed(ConstRouters.employeelogin); }, ), ], ), ), ], ), ), ), ), ), ), ), ), ); } }