import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:muaawana/config/country_codes.dart'; import 'package:muaawana/providers/auth_provider.dart'; import '../../config/app_constant.dart'; import '../../config/lang_enum.dart'; import '../../config/provider.dart'; import '../../config/size.dart'; import '../../config/style.dart'; import '../../providers/language_provider.dart'; import '../../utils/text_style.dart'; import '../../utils/text_widget.dart'; import '../../widgets/country_code_picker.dart'; import '../../widgets/custom_botton_widget.dart'; import '../../widgets/custom_search_textfield.dart'; import '../../widgets/home_indicator_widget.dart'; import 'login_view.dart'; class RegisterScreen extends StatefulWidget { const RegisterScreen({Key? key, required this.isFromSplash}) : super(key: key); final bool isFromSplash; @override State createState() => _RegisterScreenState(); } class _RegisterScreenState extends State { final hm = SizeConfig.heightMultiplier; final wm = SizeConfig.widthMultiplier; final tm = SizeConfig.textMultiplier; final TextEditingController _emailTextEditingController = TextEditingController(); final TextEditingController _passwordTextEditingController = TextEditingController(); final TextEditingController _nameTextEditingController = TextEditingController(); final TextEditingController _phoneNumberTextEditingController = TextEditingController(); final _formKey = GlobalKey(); bool check1 = false; bool _obscurePassword = true; /// Starts on Oman; the picker replaces it. Map _country = defaultCountry; bool get _isFormFilled => check1 && _nameTextEditingController.text.trim().isNotEmpty && _emailTextEditingController.text.trim().isNotEmpty && _passwordTextEditingController.text.isNotEmpty && _phoneNumberTextEditingController.text.trim().isNotEmpty; @override void initState() { super.initState(); // Without these the Continue button kept its disabled colour until some // unrelated rebuild happened. for (final controller in [ _nameTextEditingController, _emailTextEditingController, _passwordTextEditingController, _phoneNumberTextEditingController, ]) { controller.addListener(_onFieldChanged); } } void _onFieldChanged() { if (mounted) setState(() {}); } @override void dispose() { _emailTextEditingController.dispose(); _passwordTextEditingController.dispose(); _nameTextEditingController.dispose(); _phoneNumberTextEditingController.dispose(); super.dispose(); } void _submit(AuthProvider registerProvider) { if (!_isFormFilled) return; if (!(_formKey.currentState?.validate() ?? false)) return; // The dial code used to be collected and then dropped, so every account // was created with a bare local number. final String phoneNumber = "${_country["dial_code"]}${_phoneNumberTextEditingController.text.trim()}"; registerProvider.signUp( context, _emailTextEditingController.text.trim(), _passwordTextEditingController.text, _nameTextEditingController.text.trim(), phoneNumber, widget.isFromSplash, ); } @override Widget build(BuildContext context) { final registerProvider = Provider.of(context); final langP = Provider.of(context); Color getColor(Set states) { const Set interactiveStates = { MaterialState.selected, MaterialState.focused, MaterialState.pressed, }; if (states.any(interactiveStates.contains)) { return Colors.transparent; } return AppStyle.textCategGrey; } final Color onSurface = Theme.of(context).colorScheme.onSurface; return Scaffold( backgroundColor: Theme.of(context).scaffoldBackgroundColor, body: SafeArea( child: SingleChildScrollView( // Lets the Continue button scroll clear of the keyboard. padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: Stack( children: [ Padding( padding: const EdgeInsets.symmetric(vertical: 60, horizontal: 30), child: GestureDetector( onTap: () { Navigator.pop(context); }, child: Container( child: langP.currentLangCode == Language.en ? SizedBox( height: 30, width: 30, child: SvgPicture.asset( Consts.arrowBackIcon, ), ) : Transform.rotate( angle: pi, child: SizedBox( height: 20, width: 20, child: SvgPicture.asset( Consts.arrowBackIcon, ), ), ), )), ), Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: EdgeInsets.only(top: hm * 5), child: Image.asset( Consts.appLogo, height: 65, ), ), Padding( padding: EdgeInsets.all(wm * 10), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Txt( text: "Create Account", style: tS("lato_bold", 26, FontWeight.bold, onSurface), ), Txt( text: "Complete the form below to continue", style: tS("pop_regular", 16, FontWeight.normal, onSurface.withOpacity(0.7)), ), SizedBox( height: hm * 3, ), CustomTextField( isRTL: langP.currentLangCode == Language.en ? false : true, controller: _nameTextEditingController, hintText: langP.translate('Full Name'), iconPosition: CustomTextFieldIconPosition.none, // onChanged: (String) {}, ), SizedBox( height: hm * 2, ), CustomTextField( isRTL: langP.currentLangCode == Language.en ? false : true, controller: _emailTextEditingController, hintText: langP.translate('Email'), iconPosition: CustomTextFieldIconPosition.none, // onChanged: (String) {}, ), SizedBox( height: hm * 2, ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: wm * 22, child: CountryCodePicker( selected: _country, onSelected: (country) => setState(() => _country = country), ), ), Expanded( child: CustomTextField( // A dial code and digits are always LTR, even // when the app is in Arabic. isRTL: false, controller: _phoneNumberTextEditingController, hintText: langP.translate('Phone Number'), iconPosition: CustomTextFieldIconPosition.none, phoneNumber: true, keyboardType: TextInputType.phone, ), ), ], ), SizedBox( height: hm * 2, ), CustomTextField( isRTL: langP.currentLangCode == Language.en ? false : true, controller: _passwordTextEditingController, hintText: langP.translate('Password'), // The eye was decorative and the field was not // masked at all. obscure: _obscurePassword, iconPosition: CustomTextFieldIconPosition.end, endIcon: Padding( padding: const EdgeInsets.symmetric(horizontal: 10.0), child: GestureDetector( onTap: () => setState( () => _obscurePassword = !_obscurePassword), child: Icon( _obscurePassword ? Icons.visibility_off : Icons.remove_red_eye, color: onSurface.withOpacity(0.6), ), ), ), ), Row( children: [ Transform.scale( scale: 0.6, child: Checkbox( shape: const CircleBorder(), value: check1, onChanged: (value) { setState(() { check1 = value!; // widget.isComplete= value; }); }, checkColor: AppStyle.primary, fillColor: MaterialStateProperty.resolveWith(getColor), ), ), Txt( text: "I accept Terms and conditions", style: tS("lato_regular", 12, FontWeight.w400, onSurface), ), ], ), Align( alignment: Alignment.center, child: Padding( padding: EdgeInsets.only(top: hm * 2, bottom: hm), child: GestureDetector( onTap: () => _submit(registerProvider), child: CustomButtonWidget( height: 44, width: 210, borderRadius: 28, fontSize: 15, fillColor: _isFormFilled ? AppStyle.buttonBlue : AppStyle.textCategGrey, borderColor: _isFormFilled ? AppStyle.buttonBlue : AppStyle.textCategGrey, textColor: AppStyle.white, text: 'Continue', fontFamily: 'lato-regular', fontWeight: FontWeight.normal, ), ), ), ), SizedBox( width: double.infinity, child: Center( // alignment: Alignment.center, child: Row( children: [ const Expanded( child: SizedBox(), ), Txt( text: "Already have an account?", style: tS( "lato_regular", 12, FontWeight.w400, onSurface, ), ), const SizedBox( width: 5, ), GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const LoginScreen( isFromSplash: true))); }, child: Txt( text: "Sign in", style: tS("lato_regular", 12, FontWeight.w700, AppStyle.buttonBlue, textDecoration: TextDecoration.underline), ), ), const Expanded(child: SizedBox()) ], ), ), ), SizedBox( height: hm * 2, ), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Padding( // padding: // const EdgeInsets.symmetric(horizontal: 5), // child: Container( // height: 45, // width: 45, // decoration: const BoxDecoration( // shape: BoxShape.circle, // color: Colors.white, // boxShadow: [ // BoxShadow( // color: Colors.black26, // blurRadius: 1, // offset: Offset( // 0.2, // 0.5, // ), // ), // ], // ), // child: Padding( // padding: const EdgeInsets.all(10), // child: Image.asset( // Consts.appleIcon, // fit: BoxFit.scaleDown, // height: 20, // width: 20, // ), // ), // ), // ), // Padding( // padding: // const EdgeInsets.symmetric(horizontal: 5), // child: Container( // height: 45, // width: 45, // decoration: const BoxDecoration( // shape: BoxShape.circle, // color: Colors.white, // boxShadow: [ // BoxShadow( // color: Colors.black26, // blurRadius: 1, // offset: Offset( // 0.2, // 0.5, // ), // ), // ], // ), // child: Padding( // padding: const EdgeInsets.all(10), // child: Image.asset( // Consts.googleIcon, // fit: BoxFit.scaleDown, // height: 20, // width: 20, // ), // ), // ), // ), // Padding( // padding: // const EdgeInsets.symmetric(horizontal: 5), // child: Container( // height: 45, // width: 45, // decoration: const BoxDecoration( // shape: BoxShape.circle, // color: Colors.white, // boxShadow: [ // BoxShadow( // color: Colors.black26, // blurRadius: 1, // offset: Offset( // 0.2, // 0.5, // ), // ), // ], // ), // child: Padding( // padding: const EdgeInsets.all(10), // child: Image.asset( // Consts.gmailIcon, // fit: BoxFit.scaleDown, // height: 20, // width: 20, // ), // ), // ), // ), // ], // ), ], ), ), SizedBox(child: HomeIndicatorBottomWidget()) ], ), ), ], ), ), ), ); } }