// ignore_for_file: prefer_const_constructors, library_private_types_in_public_api import 'package:auth_buttons/auth_buttons.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_application_1/Project/LoginPage/login_project.dart'; import 'package:flutter_application_1/Project/utils/colors.dart'; import 'package:string_validator/string_validator.dart'; bool _obscureText = true; bool isLoading = false; String? _selectedSchool; class SignupProject extends StatefulWidget { const SignupProject({Key? key}) : super(key: key); @override _SignupProjectState createState() => _SignupProjectState(); } class _SignupProjectState extends State { final FirebaseAuth _auth = FirebaseAuth.instance; final GlobalKey _formKey = GlobalKey(); late String _email, _password; late String _firstName, _lastName, _phone, _studentID, _school; @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(36), child: AppBar( leading: IconButton( icon: const Icon(Icons.arrow_back_ios), color: Colors.black, onPressed: () { // Clear the selected school setState(() { _selectedSchool = null; _firstName = ''; _lastName = ''; _email = ''; _school = ''; _password = ''; _phone = ''; _studentID = ''; }); // Navigate back to the previous screen Navigator.of(context).pop(); }, ), title: Column( children: const [ Center( child: Text( 'Create Account', style: TextStyle( color: kBackgroundColor, fontSize: 18, fontWeight: FontWeight.w700), ), ), ], ), backgroundColor: Colors.transparent, elevation: 0, actions: [ IconButton( onPressed: () {}, icon: Icon(Icons.more_vert), ) ], ), ), body: Form( key: _formKey, child: Padding( padding: const EdgeInsets.all(12.0), child: ListView( scrollDirection: Axis.vertical, keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Create Account', style: TextStyle( color: kBackgroundColor, fontSize: 35, fontWeight: FontWeight.w500), ), RichText( text: TextSpan( text: 'Enter your name email and password \nfor sign up. ', style: TextStyle( height: 1.3, color: Color(0xff868686), fontSize: 13, fontWeight: FontWeight.w400, ), children: const [ TextSpan( text: 'Already have an account? ', style: TextStyle( color: kGreenColor, fontWeight: FontWeight.w400, ), ), ], ), ), SizedBox(height: 15), TextFormField( // First name keyboardType: TextInputType.name, textCapitalization: TextCapitalization.words, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your first name'; } else if (!isAlpha(value)) { return 'Only Letters Please'; } return null; }, onSaved: (value) => _firstName = value!.trim(), decoration: InputDecoration( isDense: true, filled: true, fillColor: Color.fromARGB(246, 246, 246, 246), contentPadding: EdgeInsets.fromLTRB(14, 18, 14, 10), labelText: 'First Name', labelStyle: TextStyle(fontSize: 14), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide( color: Color.fromARGB(232, 232, 232, 232), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), ), ), ), SizedBox(height: 10), TextFormField( // Last name keyboardType: TextInputType.name, textCapitalization: TextCapitalization.words, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your last name'; } else if (!isAlpha(value)) { return 'Only Letters Please'; } return null; }, onSaved: (input) => _lastName = input!.trim(), decoration: InputDecoration( isDense: true, filled: true, fillColor: Color.fromARGB(246, 246, 246, 246), contentPadding: EdgeInsets.fromLTRB(14, 18, 14, 10), labelText: 'Last Name', labelStyle: TextStyle(fontSize: 14), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide( color: Color.fromARGB(232, 232, 232, 232), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), ), ), ), SizedBox(height: 10), TextFormField( // student ID keyboardType: TextInputType.phone, textInputAction: TextInputAction.next, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(10) ], validator: (value) { if (value!.isEmpty) { return 'Please enter your Student ID'; } else if (isAlpha(value)) { return 'Only Numbers Please'; } else if (value.length < 10) { return 'Please enter a VALID Student ID'; } return null; }, onSaved: (input) => _studentID = input!, decoration: InputDecoration( isDense: true, filled: true, fillColor: Color.fromARGB(246, 246, 246, 246), contentPadding: EdgeInsets.fromLTRB(14, 18, 14, 10), labelText: 'Student ID', labelStyle: TextStyle(fontSize: 14), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide( color: Color.fromARGB(232, 232, 232, 232), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), ), ), ), SizedBox(height: 10), DropdownButtonFormField( value: _selectedSchool, onChanged: (String? newValue) { setState(() { _selectedSchool = newValue; }); }, items: const [ DropdownMenuItem( value: 'School of Liberal Arts', child: Text('School of Liberal Arts'), ), DropdownMenuItem( value: 'School of Science', child: Text('School of Science'), ), DropdownMenuItem( value: 'School of Management', child: Text('School of Management'), ), DropdownMenuItem( value: 'School of Information Technology', child: Text('School of Information Technology'), ), DropdownMenuItem( value: 'School of Agro-Industry', child: Text('School of Agro-Industry'), ), DropdownMenuItem( value: 'School of Law', child: Text('School of Law'), ), DropdownMenuItem( value: 'School of Cosmetic Science', child: Text('School of Cosmetic Science'), ), DropdownMenuItem( value: 'School of Health Sciences', child: Text('School of Health Sciences'), ), DropdownMenuItem( value: 'School of Nursing', child: Text('School of Nursing'), ), DropdownMenuItem( value: 'School of Anti-Aging Medicine', child: Text('School of Anti-Aging Medicine'), ), DropdownMenuItem( value: 'School of Medicine', child: Text('School of Medicine'), ), DropdownMenuItem( value: 'School of Dentistry', child: Text('School of Dentistry'), ), DropdownMenuItem( value: 'dental clinic School of Dentistry', child: Text('dental clinic School of Dentistry'), ), DropdownMenuItem( value: 'School of Social Innovation', child: Text('School of Social Innovation'), ), DropdownMenuItem( value: 'School of Chinese Sciences', child: Text('School of Chinese Sciences'), ), DropdownMenuItem( value: 'School of Integrative Medicine', child: Text('School of Integrative Medicine'), ), ], onSaved: (input) => _school = input!, decoration: InputDecoration( isDense: true, filled: true, fillColor: Color.fromARGB(246, 246, 246, 246), contentPadding: EdgeInsets.fromLTRB(14, 18, 14, 10), labelText: 'School of', labelStyle: TextStyle(fontSize: 14), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide( color: Color.fromARGB(232, 232, 232, 232), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Please Select your school'; } return null; }, ), SizedBox(height: 10), TextFormField( // Phone number keyboardType: TextInputType.phone, textInputAction: TextInputAction.next, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(9) ], validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your phone number'; } else if (isAlpha(value)) { return 'Only Numbers Please'; } else if (value.length < 9) { return 'Please enter a VALID phone number'; } return null; }, onSaved: (input) => _phone = input!, decoration: InputDecoration( isDense: true, filled: true, fillColor: Color.fromARGB(246, 246, 246, 246), contentPadding: EdgeInsets.fromLTRB(14, 18, 14, 10), labelText: 'Phone Number', prefixText: '(+66) ', labelStyle: TextStyle(fontSize: 14), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide( color: Color.fromARGB(232, 232, 232, 232), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), ), ), ), SizedBox(height: 10), TextFormField( // Email keyboardType: TextInputType.emailAddress, textCapitalization: TextCapitalization.words, textInputAction: TextInputAction.next, validator: (value) { if (value!.isEmpty) { return 'Please enter an email address'; } else if (!RegExp(r"^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$") .hasMatch(value)) { return 'Please enter a valid email address'; } return null; }, onSaved: (input) => _email = input!.trim(), decoration: InputDecoration( isDense: true, filled: true, fillColor: Color.fromARGB(246, 246, 246, 246), contentPadding: EdgeInsets.fromLTRB(14, 18, 14, 10), labelText: 'Email Address', labelStyle: TextStyle(fontSize: 14), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide( color: Color.fromARGB(232, 232, 232, 232), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), ), ), ), SizedBox(height: 10), TextFormField( textInputAction: TextInputAction.done, validator: (input) { if (input!.length < 8) { return 'Your password needs to be at least 8 characters'; } else if (input.isEmpty) { return 'Please enter your password'; } }, onSaved: (input) => _password = input!.trim(), decoration: InputDecoration( isDense: true, filled: true, fillColor: Color.fromARGB(246, 246, 246, 246), contentPadding: EdgeInsets.fromLTRB(14, 18, 14, 10), labelText: 'Password', labelStyle: TextStyle(fontSize: 14), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: BorderSide( color: Color.fromARGB(232, 232, 232, 232), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), ), suffixIcon: IconButton( icon: Icon( _obscureText ? Icons.visibility : Icons.visibility_off, color: Colors.grey, ), onPressed: () { setState(() { _obscureText = !_obscureText; }); }, ), ), obscureText: _obscureText, ), SizedBox(height: 15), Center( child: ElevatedButton( onPressed: signUp, style: ElevatedButton.styleFrom( backgroundColor: kGreenColor, foregroundColor: kWhiteColor, padding: EdgeInsets.all(13), minimumSize: Size(350, 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), child: Text( 'REGISTER', ), ), ), SizedBox(height: 15), Text( ' By Signing up you agree to our Terms Conditions & Privacy Policy.', style: TextStyle( height: 1.3, color: Color(0xff868686), fontSize: 13, fontWeight: FontWeight.w400, ), textAlign: TextAlign.center, ), ], ), ], ), ), ), ); } Future signUp() async { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); try { UserCredential userCredential = await _auth.createUserWithEmailAndPassword( email: _email, password: _password, ); // Create a Firestore document for the new user FirebaseFirestore.instance .collection('users') .doc(userCredential.user!.uid) .set({ 'firstName': _firstName, 'lastName': _lastName, 'phone': '+66$_phone', 'studentID': _studentID, 'school': _school, 'email': _email, 'image_url': 'https://firebasestorage.googleapis.com/v0/b/project-tongz-1.appspot.com/o/admin_images%2Fd4c961732ba6ec52c0bbde63c9cb9e5dd6593826ee788080599f68920224e27d.jpg?alt=media&token=c6c0f02a-56d5-47b7-8933-3fa946f4f033', 'uid': userCredential.user!.uid, 'role': 'user', }); // Clear form fields _formKey.currentState!.reset(); _firstName = ''; _lastName = ''; _email = ''; _school = ''; _password = ''; _phone = ''; _studentID = ''; // Clear selected school setState(() { _selectedSchool = null; }); // Add user's first and last name to their account await userCredential.user?.updateDisplayName( '$_firstName $_lastName $_phone $_studentID $_school'); // Send email verification await sendEmailVerification(context); // ignore: use_build_context_synchronously Navigator.push( context, MaterialPageRoute(builder: (context) => const LoginProject()), ); } on FirebaseAuthException catch (e) { if (e.code == 'weak-password') { debugPrint('The password provided is too weak.'); } else if (e.code == 'email-already-in-use') { debugPrint('The account already exists for that email.'); } } catch (e) { // ignore: avoid_print print(e); } } } //EMAIL VERIFICATION Future sendEmailVerification(BuildContext context) async { try { _auth.currentUser!.sendEmailVerification(); showSnackBar(context, 'Email verification sent!'); } on FirebaseAuthException catch (e) { showSnackBar(context, e.message!); // Display error message } } } void showSnackBar(BuildContext context, String text) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(text), ), ); }