import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_otp_text_field/flutter_otp_text_field.dart'; import 'package:injector/injector.dart'; import 'package:prosappco/blocs/auth_bloc/auth_bloc.dart'; import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart'; import 'package:prosappco/components/general_primary_button.dart'; final _formKey = GlobalKey(); class ProfileRegisterEmailScreen extends StatefulWidget { const ProfileRegisterEmailScreen({super.key}); @override State createState() => _ProfileRegisterEmailScreenState(); } class _ProfileRegisterEmailScreenState extends State { final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); final TextEditingController _confirmPasswordController = TextEditingController(); late final AuthBloc authBloc; late String verificationCode; String? validateEmail(String? email) { RegExp emailRegex = RegExp(r'^[\w\.-]+@[\w-]+\.\w{2,3}(\.\w{2,3})?$'); final isEmailValid = emailRegex.hasMatch(email ?? ''); if (isEmailValid) { return null; } else { return 'Ingresa un correo electronico valido'; } } String? validatePassword(String? password) { RegExp passwordRegex = RegExp(r'^(?=.*?[0-9])'); final isPasswordValid = passwordRegex.hasMatch(password ?? ''); if (isPasswordValid) { return null; } else { return 'La contraseña debe tener al menos un número'; } } @override void initState() { super.initState(); authBloc = Injector.appInstance.get(); } @override void dispose() { _emailController.dispose(); _passwordController.dispose(); _confirmPasswordController.dispose(); super.dispose(); } void _showLoginModal(BuildContext context, MyUserState state) { final authBlocDialog = Injector.appInstance.get(); final phone = state.user?.phone ?? ''; authBlocDialog.add(AuthEventLoginOAuth(phone: phone)); showDialog( context: context, builder: (BuildContext context) { return BlocProvider( create: (context) => authBlocDialog, child: BlocConsumer( listener: (context, state) { if (state is AuthStateSuccess) { authBloc.add( AuthEventAddEmailAndPassword( email: _emailController.text, password: _passwordController.text, ), ); } else if (state is AuthStateVerifyOAuth && state.isWrongCode) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text('El Código es incorrecto'), )); } }, builder: (context, state) { return AlertDialog( content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ const Text( 'Te enviaremos un código \n de verificación a', textAlign: TextAlign.center, ), const SizedBox(height: 20), Text( phone, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 20), OtpTextField( numberOfFields: 6, fieldWidth: 35, borderColor: const Color(0xFF512DA8), onCodeChanged: (String code) { verificationCode = code; }, onSubmit: (String verificationCode) { authBlocDialog.add( AuthEventVerifyOAuth(code: verificationCode)); }, ), const SizedBox(height: 30), GeneralPrimaryButton( onPressed: () { authBlocDialog.add( AuthEventVerifyOAuth(code: verificationCode)); }, label: 'Continuar', ), ], ), ); }, ), ); }); } @override Widget build(BuildContext context) { return BlocProvider( create: (context) => authBloc, child: BlocListener( listener: (context, state) { if (state is AuthStateSuccess) { Navigator.of(context).pop(); } if (state is AuthStateEmailAlreadyInUse) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text('El correo ya existe'), )); Navigator.of(context).pop(); } if (state is AuthStateRequiresRecentLogin) {} }, child: BlocBuilder( builder: (context, state) { if (state.status == MyUserStatus.success) { _emailController.text = state.user!.email ?? ''; return Scaffold( appBar: AppBar( title: const Text('Agregar correo'), ), body: Column( children: [ Expanded( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric( horizontal: 40, vertical: 10), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextFormField( controller: _emailController, decoration: InputDecoration( labelText: 'Email', prefixIcon: const Icon(Icons.email_rounded), hintText: 'Email', border: inputBorder(), errorBorder: inputBorderError(), focusedErrorBorder: inputBorderFocus(), ), validator: validateEmail, autovalidateMode: AutovalidateMode.onUserInteraction, ), const SizedBox(height: 20), TextFormField( controller: _passwordController, obscureText: true, decoration: InputDecoration( labelText: 'Contraseña', prefixIcon: const Icon(Icons.lock_rounded), hintText: 'Contraseña', border: inputBorder(), errorBorder: inputBorderError(), focusedErrorBorder: inputBorderFocus(), ), validator: validatePassword, autovalidateMode: AutovalidateMode.onUserInteraction, ), const SizedBox(height: 20), TextFormField( controller: _confirmPasswordController, obscureText: true, decoration: InputDecoration( labelText: 'Confirmar contraseña', prefixIcon: const Icon(Icons.lock_rounded), hintText: 'Contraseña', border: inputBorder(), errorBorder: inputBorderError(), focusedErrorBorder: inputBorderFocus(), ), validator: (value) { if (value != _passwordController.text) { return 'Las contraseñas no coinciden'; } if (value!.isEmpty) { return 'La contraseña es obligatoria'; } return null; }, autovalidateMode: AutovalidateMode.onUserInteraction, ), const SizedBox(height: 30), ], ), ), ), ), ), const Divider( height: 1, thickness: 0.5, ), Padding( padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 15, ), child: FilledButton( onPressed: () { if (_formKey.currentState!.validate()) { _showLoginModal(context, state); } }, style: FilledButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, padding: const EdgeInsets.symmetric(vertical: 15), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), child: Container( alignment: Alignment.center, width: double.infinity, child: const Text( 'Guardar', style: TextStyle(color: Colors.white, fontSize: 18), ), ), ), ), ], ), ); } else { return const Center(child: CircularProgressIndicator()); } }, ), ), ); } OutlineInputBorder inputBorderFocus() { return OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 2.0, ), ); } OutlineInputBorder inputBorderError() { return OutlineInputBorder( borderSide: BorderSide(color: Colors.red), ); } OutlineInputBorder inputBorder() { return OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(10.0), ), ); } }