import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:kmobile/app.dart'; import 'package:kmobile/features/auth/screens/mpin_screen.dart'; import 'package:kmobile/features/auth/screens/set_password_screen.dart'; import 'package:kmobile/features/auth/screens/tnc_required_screen.dart'; import 'package:kmobile/widgets/tnc_dialog.dart'; import '../../../l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import '../controllers/auth_cubit.dart'; import '../controllers/auth_state.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override LoginScreenState createState() => LoginScreenState(); } class LoginScreenState extends State with SingleTickerProviderStateMixin { final _formKey = GlobalKey(); final _customerNumberController = TextEditingController(); final _passwordController = TextEditingController(); bool _obscurePassword = true; @override void dispose() { _customerNumberController.dispose(); _passwordController.dispose(); super.dispose(); } void _submitForm() { if (_formKey.currentState!.validate()) { context.read().login( _customerNumberController.text.trim(), _passwordController.text, ); } } @override Widget build(BuildContext context) { // return Scaffold( // body: BlocConsumer( // listener: (context, state) async { // if (state is ShowTncDialog) { // // The dialog now returns a boolean for the 'disagree' case, // // or it completes when the 'proceed' action is finished. // final agreed = await showDialog( // context: context, // barrierDismissible: false, // builder: (dialogContext) => TncDialog( // onProceed: () async { // // This function is passed to the dialog. // // It calls the cubit and completes when the cubit's work is done. // await context // .read() // .onTncDialogResult(true, state.authToken, state.users); // }, // ), // ); // // If 'agreed' is false, it means the user clicked 'Disagree'. // if (agreed == false) { // if (!context.mounted) return; // context // .read() // .onTncDialogResult(false, state.authToken, state.users); // } // } else if (state is NavigateToTncRequiredScreen) { // Navigator.of(context).pushNamed(TncRequiredScreen.routeName); // } else if (state is NavigateToMpinSetupScreen) { // Navigator.of(context).push( // Use push, NOT pushReplacement // MaterialPageRoute( // builder: (_) => MPinScreen( // mode: MPinMode.set, // onCompleted: (_) { // // This clears the entire stack and pushes the dashboard // Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( // MaterialPageRoute(builder: (_) => const NavigationScaffold()), // (route) => false, // ); // }, // ), // ), // ); // } else if (state is NavigateToDashboardScreen) { // Navigator.of(context).pushReplacement( // MaterialPageRoute(builder: (_) => const NavigationScaffold()), // ); // } else if (state is AuthError) { // if (state.message == 'MIGRATED_USER_HAS_NO_PASSWORD') { // Navigator.of(context).push(MaterialPageRoute( // builder: (_) => SetPasswordScreen( // customerNo: _customerNumberController.text.trim(), // ))); // } else { // ScaffoldMessenger.of(context) // .showSnackBar(SnackBar(content: Text(state.message))); // } // } // }, // builder: (context, state) { // // The commented out section is removed for clarity, the logic is now above. // return Padding( // padding: const EdgeInsets.all(24.0), // child: Form( // key: _formKey, // child: Column( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Image.asset( // 'assets/images/logo.png', // width: 150, // height: 150, // errorBuilder: (context, error, stackTrace) { // return Icon( // Icons.account_balance, // size: 100, // color: Theme.of(context).primaryColor, // ); // }, // ), // const SizedBox(height: 16), // Text( // AppLocalizations.of(context).kccb, // style: TextStyle( // fontSize: 32, // fontWeight: FontWeight.bold, // color: Theme.of(context).primaryColor, // ), // ), // const SizedBox(height: 48), // TextFormField( // controller: _customerNumberController, // decoration: InputDecoration( // labelText: AppLocalizations.of(context).customerNumber, // border: const OutlineInputBorder(), // isDense: true, // filled: true, // fillColor: Theme.of(context).scaffoldBackgroundColor, // enabledBorder: OutlineInputBorder( // borderSide: BorderSide( // color: Theme.of(context).colorScheme.outline), // ), // focusedBorder: OutlineInputBorder( // borderSide: BorderSide( // color: Theme.of(context).colorScheme.primary, // width: 2), // ), // ), // keyboardType: TextInputType.number, // textInputAction: TextInputAction.next, // validator: (value) { // if (value == null || value.isEmpty) { // return AppLocalizations.of(context).pleaseEnterUsername; // } // return null; // }, // ), // const SizedBox(height: 24), // TextFormField( // controller: _passwordController, // obscureText: _obscurePassword, // textInputAction: TextInputAction.done, // onFieldSubmitted: (_) => _submitForm(), // decoration: InputDecoration( // labelText: AppLocalizations.of(context).password, // border: const OutlineInputBorder(), // isDense: true, // filled: true, // fillColor: Theme.of(context).scaffoldBackgroundColor, // enabledBorder: OutlineInputBorder( // borderSide: BorderSide( // color: Theme.of(context).colorScheme.outline), // ), // focusedBorder: OutlineInputBorder( // borderSide: BorderSide( // color: Theme.of(context).colorScheme.primary, // width: 2), // ), // suffixIcon: IconButton( // icon: Icon( // _obscurePassword // ? Icons.visibility // : Icons.visibility_off, // ), // onPressed: () { // setState(() { // _obscurePassword = !_obscurePassword; // }); // }, // ), // ), // validator: (value) { // if (value == null || value.isEmpty) { // return AppLocalizations.of(context).pleaseEnterPassword; // } // return null; // }, // ), // const SizedBox(height: 24), // SizedBox( // width: 250, // child: ElevatedButton( // onPressed: state is AuthLoading ? null : _submitForm, // style: ElevatedButton.styleFrom( // shape: const StadiumBorder(), // padding: const EdgeInsets.symmetric(vertical: 16), // backgroundColor: // Theme.of(context).scaffoldBackgroundColor, // foregroundColor: Theme.of(context).primaryColorDark, // side: BorderSide( // color: Theme.of(context).colorScheme.outline, // width: 1), // elevation: 0, // ), // child: state is AuthLoading // ? const CircularProgressIndicator() // : Text( // AppLocalizations.of(context).login, // style: TextStyle( // color: Theme.of(context) // .colorScheme // .onPrimaryContainer), // ), // ), // ), // const SizedBox(height: 25), // ], // ), // ), // ); // }, // ), // ); return Scaffold( body: BlocConsumer( listener: (context, state) { if (state is ShowTncDialog) { showDialog( context: context, barrierDismissible: false, builder: (dialogContext) => TncDialog( onProceed: () async { // Pop the dialog before the cubit action Navigator.of(dialogContext).pop(); await context .read() .onTncDialogResult(true, state.authToken, state.users); }, ), ); } else if (state is NavigateToTncRequiredScreen) { Navigator.of(context).pushNamed(TncRequiredScreen.routeName); } else if (state is NavigateToMpinSetupScreen) { Navigator.of(context).push( // Use push, NOT pushReplacement MaterialPageRoute( builder: (_) => MPinScreen( mode: MPinMode.set, onCompleted: (_) { // Call the cubit to signal MPIN setup is complete context.read().mpinSetupCompleted(); }, ), ), ); } else if (state is Authenticated) { // This is the single source of truth for navigating to the dashboard Navigator.of(context, rootNavigator: true).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const NavigationScaffold()), (route) => false, ); } else if (state is AuthError) { if (state.message == 'MIGRATED_USER_HAS_NO_PASSWORD') { Navigator.of(context).push(MaterialPageRoute( builder: (_) => SetPasswordScreen( customerNo: _customerNumberController.text.trim(), ))); } else { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text(state.message))); } } }, builder: (context, state) { // The builder part remains largely the same, focusing on UI display return Padding( padding: const EdgeInsets.all(24.0), child: Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'assets/images/logo.png', width: 150, height: 150, errorBuilder: (context, error, stackTrace) { return Icon( Icons.account_balance, size: 100, color: Theme.of(context).primaryColor, ); }, ), const SizedBox(height: 16), Text( AppLocalizations.of(context).kccb, style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, color: Theme.of(context).primaryColor, ), ), const SizedBox(height: 48), TextFormField( controller: _customerNumberController, decoration: InputDecoration( labelText: AppLocalizations.of(context).customerNumber, border: const OutlineInputBorder(), isDense: true, filled: true, fillColor: Theme.of(context).scaffoldBackgroundColor, enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Theme.of(context).colorScheme.outline), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Theme.of(context).colorScheme.primary, width: 2), ), ), keyboardType: TextInputType.number, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return AppLocalizations.of(context).pleaseEnterUsername; } return null; }, ), const SizedBox(height: 24), TextFormField( controller: _passwordController, obscureText: _obscurePassword, textInputAction: TextInputAction.done, onFieldSubmitted: (_) => _submitForm(), decoration: InputDecoration( labelText: AppLocalizations.of(context).password, border: const OutlineInputBorder(), isDense: true, filled: true, fillColor: Theme.of(context).scaffoldBackgroundColor, enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Theme.of(context).colorScheme.outline), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Theme.of(context).colorScheme.primary, width: 2), ), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility : Icons.visibility_off, ), onPressed: () { setState(() { _obscurePassword = !_obscurePassword; }); }, ), ), validator: (value) { if (value == null || value.isEmpty) { return AppLocalizations.of(context).pleaseEnterPassword; } return null; }, ), const SizedBox(height: 24), SizedBox( width: 250, child: ElevatedButton( onPressed: state is AuthLoading ? null : _submitForm, style: ElevatedButton.styleFrom( shape: const StadiumBorder(), padding: const EdgeInsets.symmetric(vertical: 16), backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: Theme.of(context).primaryColorDark, side: BorderSide( color: Theme.of(context).colorScheme.outline, width: 1), elevation: 0, ), child: state is AuthLoading ? const CircularProgressIndicator() : Text( AppLocalizations.of(context).login, style: TextStyle( color: Theme.of(context) .colorScheme .onPrimaryContainer), ), ), ), const SizedBox(height: 25), ], ), ), ); }, ), ); } }