Untitled
part of '../pages.dart'; class SignUpPage extends StatefulWidget { const SignUpPage({super.key}); @override State<SignUpPage> createState() => _SignUpPageState(); } class _SignUpPageState extends State<SignUpPage> { bool isObscureText = true; bool isLoading = false; final _auth = FirebaseService(); final _firebaseStore = FirebaseFirestore.instance; final _formKey = GlobalKey<FormState>(); String? _selectedRole; TextEditingController emailController = TextEditingController(); TextEditingController passwordController = TextEditingController(); TextEditingController confirmPasswordController = TextEditingController(); TextEditingController firstNameController = TextEditingController(); TextEditingController lastNameController = TextEditingController(); TextEditingController roleController = TextEditingController(); void _signUp() async { if (_formKey.currentState!.validate()) { setState(() { isLoading = true; }); } try { User? user = (await _auth.signUp(emailController.text, passwordController.text)); if (user != null) { await _firebaseStore.collection('users').doc(user.uid).set({ 'email': emailController.text, 'first_name': firstNameController.text, 'last_name': lastNameController.text, 'role' : _selectedRole }); Navigator.pushReplacementNamed(context, '/home'); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Registerasi berhasil! ${user.email}'))); } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(e.toString()), ), ); setState(() { isLoading = false; }); } finally { setState(() { isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, body: Center( child: Form( key: _formKey, child: ListView( children: [ Column( children: [ const SizedBox(height: 50), // image Container( width: MediaQuery.of(context).size.width * 0.9, height: 200, decoration: BoxDecoration( color: Colors.amber, borderRadius: BorderRadius.circular(10), image: DecorationImage( image: imageLogo, fit: BoxFit.cover, ), ), ), const SizedBox(height: 20), // welcome text SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: Text( welcomeText, style: welcomeTextStyle, ), ), const SizedBox(height: 10), // text subWelcome SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: Text( subWelcomeText, style: subWelcomeTextStyle, ), ), const SizedBox(height: 20), // email SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: TextFormField( controller: emailController, decoration: InputDecoration( hintText: hintEmail, prefixIcon: Icon(Icons.email), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return 'email cannot be empty'; } if (!RegExp( r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") .hasMatch(value)) { return 'invalid email'; } return null; }, ), ), const SizedBox(height: 10), // list name SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // First Name Expanded( child: TextFormField( controller: firstNameController, decoration: InputDecoration( hintText: hintFirstName, prefixIcon: Icon(Icons.person), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), keyboardType: TextInputType.name, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return 'first name cannot be empty'; } return null; }, ), ), const SizedBox(width: 10), // Last Name Expanded( child: TextFormField( controller: lastNameController, decoration: InputDecoration( hintText: hintLastName, prefixIcon: Icon(Icons.person), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), keyboardType: TextInputType.name, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return 'last name cannot be empty'; } return null; }, ), ), ], ), ), const SizedBox(height: 10), // choose role SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: DropdownButtonFormField<String>( value: _selectedRole, hint: Text( 'Select Role', style: TextStyle(color: Colors.black54, fontSize: 16), // Custom font style ), items: ['User', 'Admin'].map((role) { return DropdownMenuItem( value: role, child: Text( role, style: TextStyle(fontSize: 16, color: Colors.black), // Font style for the items ), ); }).toList(), onChanged: (value) => setState(() => _selectedRole = value), validator: (value) => value == null ? 'Please select a role' : null, decoration: InputDecoration( contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 15), // Padding inside the dropdown border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), prefixIcon: Icon(Icons.person), // Adding person icon here ), ), ), const SizedBox(height: 10), // password SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: TextFormField( controller: passwordController, decoration: InputDecoration( hintText: hintPassword, prefixIcon: Icon(Icons.lock), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), suffixIcon: IconButton( onPressed: () { setState(() { isObscureText = !isObscureText; }); }, icon: isObscureText ? Icon( Icons.visibility_off_outlined, color: colorPrimary, ) : Icon( Icons.visibility, color: colorPrimary, ), ), ), obscureText: isObscureText ? true : false, keyboardType: TextInputType.visiblePassword, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return 'password cannot be empty'; } if (value.length <= 6) { return 'password at least 6 characters'; } return null; }, ), ), const SizedBox(height: 10), // confirm SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: TextFormField( controller: confirmPasswordController, decoration: InputDecoration( hintText: hintConfirmPassword, prefixIcon: Icon(Icons.lock), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), suffixIcon: IconButton( onPressed: () { setState(() { isObscureText = !isObscureText; }); }, icon: isObscureText ? Icon( Icons.visibility_off_outlined, color: colorPrimary, ) : Icon( Icons.visibility, color: colorPrimary, ), ), ), obscureText: isObscureText ? true : false, keyboardType: TextInputType.visiblePassword, textInputAction: TextInputAction.done, validator: (value) { if (value == null || value.isEmpty) { return 'password cannot be empty'; } if (value.length <= 6) { return 'password at least 6 characters'; } if (value != passwordController.text) { return 'password is not same'; } return null; }, ), ), const SizedBox(height: 10), // forgot SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: GestureDetector( onTap: () { print(hintForgotPassword); }, child: Text( hintForgotPassword, textAlign: TextAlign.end, style: subWelcomeTextStyle, ), ), ), const SizedBox(height: 10), // button signUp SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: isLoading ? Center( child: CircularProgressIndicator(), ) : ElevatedButton( onPressed: () { _signUp(); }, style: ElevatedButton.styleFrom( backgroundColor: colorPrimary, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), child: Text(hintSignUp, style: hintTextStyle)), ), const SizedBox(height: 10), // text other signUp SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: Text( hintOtherSignUpOptions, style: subWelcomeTextStyle, textAlign: TextAlign.center, ), ), const SizedBox(height: 10), // verify with google & facebook SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( children: [ Container( width: 40, height: 40, margin: EdgeInsets.all(8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(25), image: DecorationImage( image: AssetImage(imageGoogle), fit: BoxFit.cover, ), ), ), Text( hintTextGoogle, style: welcomeTextStyle.copyWith(fontSize: 14), ), ], ), Row( children: [ Container( width: 40, height: 40, margin: EdgeInsets.all(8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(25), image: DecorationImage( image: AssetImage(imageFacebook), fit: BoxFit.cover, ), ), ), Text(hintTextFacebook, style: welcomeTextStyle.copyWith(fontSize: 14)), ], ), ], ), ), const SizedBox(height: 10), SizedBox( width: MediaQuery.of(context).size.width * 0.9, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( hintAlreadyHaveAccount, style: subWelcomeTextStyle, ), const SizedBox(width: 5), GestureDetector( onTap: () { Navigator.pushNamed(context, '/sign-in'); }, child: Text(hintSignIn)) ], ), ), const SizedBox(height: 20), ], ), ], ), ), ), ); } }
Leave a Comment