diff --git a/lib/main.dart b/lib/main.dart index 236a923..0aaf022 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/provider/google_sign.dart'; import 'package:prosappco/src/screens/login.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -18,12 +20,13 @@ void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, - ); + ).then((value) => Get.put(AuthenticationRepository())); runApp(const MyApp()); } final FirebaseAuth _auth = FirebaseAuth.instance; final GoogleSignIn googleSignIn = GoogleSignIn(); + Future signInWithGoogle() async { final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); final GoogleSignInAuthentication googleSignInAuthentication = @@ -42,20 +45,11 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - if (_auth.currentUser == null) { - return MaterialApp( - theme: ThemeData(fontFamily: 'Poppins'), - debugShowCheckedModeBanner: false, - title: 'ProsApp', - home: LoginScreen(), - ); - } else { - return MaterialApp( - theme: ThemeData(fontFamily: 'Poppins'), - debugShowCheckedModeBanner: false, - title: 'ProsApp', - home: WelcomeScreen(), - ); - } + return GetMaterialApp( + theme: ThemeData(fontFamily: 'Poppins'), + debugShowCheckedModeBanner: false, + title: 'ProsApp', + home: const LoginScreen(), + ); } } diff --git a/lib/src/authentication/authentication_repository.dart b/lib/src/authentication/authentication_repository.dart new file mode 100644 index 0000000..eaddc4b --- /dev/null +++ b/lib/src/authentication/authentication_repository.dart @@ -0,0 +1,70 @@ +import 'dart:ffi'; + +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:get/get.dart'; +import 'package:google_sign_in/google_sign_in.dart'; +import 'package:prosappco/src/authentication/exceptions/register_failed.dart'; +import 'package:prosappco/src/screens/login.dart'; +import 'package:prosappco/src/screens/welcome.dart'; + +class AuthenticationRepository extends GetxController { + static AuthenticationRepository get instance => Get.find(); + + //Variables + final _auth = FirebaseAuth.instance; + late final Rx firebaseUser; + final GoogleSignIn googleSignIn = GoogleSignIn(); + + @override + void onReady() { + Future.delayed(const Duration(seconds: 6)); + firebaseUser = Rx(_auth.currentUser); + firebaseUser.bindStream(_auth.userChanges()); + ever(firebaseUser, _setInitialScreen); + } + + _setInitialScreen(User? user) { + user == null + ? Get.offAll(() => const LoginScreen()) + : Get.offAll(() => const WelcomeScreen()); + } + + Future createUserWithEmailAndPassword( + String email, String password) async { + try { + await _auth.createUserWithEmailAndPassword( + email: email, password: password); + firebaseUser.value != null + ? Get.offAll(() => WelcomeScreen()) + : Get.to(() => LoginScreen()); + } on FirebaseAuthException catch (e) { + final ex = SignUpWithEmailAndPasswordFailure.code(e.code); + print('FIREBASE AUTH EXCEPTION - ${ex.message}'); + } catch (_) { + const ex = SignUpWithEmailAndPasswordFailure(); + print('EXCEPTION - ${ex.message}'); + throw ex; + } + } + + Future loginWithEmailAndPassword(String email, String password) async { + try { + await _auth.signInWithEmailAndPassword(email: email, password: password); + } on FirebaseAuthException catch (e) { + } catch (_) {} + } + + Future signInWithGoogle() async { + final GoogleSignInAccount? googleSignInAccount = + await googleSignIn.signIn(); + final GoogleSignInAuthentication googleSignInAuthentication = + await googleSignInAccount!.authentication; + + final AuthCredential credential = GoogleAuthProvider.credential( + accessToken: googleSignInAuthentication.accessToken, + idToken: googleSignInAuthentication.idToken, + ); + + return await _auth.signInWithCredential(credential); + } +} diff --git a/lib/src/authentication/exceptions/register_failed.dart b/lib/src/authentication/exceptions/register_failed.dart new file mode 100644 index 0000000..f2c6fd4 --- /dev/null +++ b/lib/src/authentication/exceptions/register_failed.dart @@ -0,0 +1,19 @@ +class SignUpWithEmailAndPasswordFailure { + final String message; + + const SignUpWithEmailAndPasswordFailure( + [this.message = "An Unknown error ocurred."]); + + factory SignUpWithEmailAndPasswordFailure.code(String code) { + switch (code) { + case 'weak-password': + return const SignUpWithEmailAndPasswordFailure( + 'Please enter a stronger password.'); + case 'email-alredy-in-use': + return const SignUpWithEmailAndPasswordFailure( + 'An account alredy exists for that email.'); + default: + return const SignUpWithEmailAndPasswordFailure(); + } + } +} diff --git a/lib/src/controllers/register_controller.dart b/lib/src/controllers/register_controller.dart new file mode 100644 index 0000000..3f09b83 --- /dev/null +++ b/lib/src/controllers/register_controller.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:prosappco/src/authentication/authentication_repository.dart'; + +class RegisterController extends GetxController { + static RegisterController get instance => Get.find(); + + // textField controllers to get data from textfields + final name = TextEditingController(); + final email = TextEditingController(); + final password = TextEditingController(); + + void registerUser(String email, String password) { + AuthenticationRepository.instance + .createUserWithEmailAndPassword(email, password); + } +} diff --git a/lib/src/screens/register.dart b/lib/src/screens/register.dart index 2b2b7aa..9a2acab 100644 --- a/lib/src/screens/register.dart +++ b/lib/src/screens/register.dart @@ -1,7 +1,9 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:get/get.dart'; import 'package:prosappco/main.dart'; +import 'package:prosappco/src/controllers/register_controller.dart'; import 'package:prosappco/src/provider/google_sign.dart'; import 'package:prosappco/src/screens/login.dart'; import 'package:prosappco/src/screens/welcome.dart'; @@ -16,6 +18,8 @@ class RegisterScreen extends StatefulWidget { class _RegisterScreenState extends State { bool _obscureText = true; + final controller = Get.put(RegisterController()); + final _formKey = GlobalKey(); @override Widget build(BuildContext context) { @@ -144,108 +148,131 @@ class _RegisterScreenState extends State { ], ), ), - const Padding( - padding: EdgeInsets.only(bottom: 5), - child: Align( - alignment: Alignment.topLeft, - child: Text('Nombre', - style: TextStyle( - fontSize: 18.0, color: Color(0xFF65676B))), - )), - const Padding( - padding: EdgeInsets.only(bottom: 18), - child: TextField( - decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), + Form( + key: _formKey, + child: Column( + children: [ + const Padding( + padding: EdgeInsets.only(bottom: 5), + child: Align( + alignment: Alignment.topLeft, + child: Text('Nombre', + style: TextStyle( + fontSize: 18.0, color: Color(0xFF65676B))), )), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - hintText: 'Nombre Apellido', - fillColor: Color.fromARGB(255, 239, 239, 239), - filled: true, - prefixIcon: Icon(Icons.person_outline)), - ), - ), - const Padding( - padding: EdgeInsets.only(bottom: 5), - child: Align( - alignment: Alignment.topLeft, - child: Text('Email', - style: TextStyle( - fontSize: 18.0, color: Color(0xFF65676B))), - )), - const Padding( - padding: EdgeInsets.only(bottom: 18), - child: TextField( - decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - hintText: 'Hello@gmail.com', - fillColor: Color.fromARGB(255, 239, 239, 239), - filled: true, - prefixIcon: Icon(Icons.email_outlined)), - ), - ), - const Padding( - padding: EdgeInsets.only(bottom: 5), - child: Align( - alignment: Alignment.topLeft, - child: Text('Password', - style: TextStyle( - fontSize: 18.0, color: Color(0xFF65676B))), - )), - Padding( - padding: EdgeInsets.only(bottom: 25), - child: TextField( - obscureText: _obscureText, - decoration: InputDecoration( - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - hintText: 'ContraseƱa', - fillColor: Color.fromARGB(255, 239, 239, 239), - filled: true, - prefixIcon: Icon(Icons.lock_outline), - suffixIcon: IconButton( - icon: Icon( - _obscureText ? Icons.visibility_off : Icons.visibility, - color: Colors.grey, + Padding( + padding: EdgeInsets.only(bottom: 18), + child: TextFormField( + controller: controller.name, + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + hintText: 'Nombre y Apellido', + fillColor: Color.fromARGB(255, 239, 239, 239), + filled: true, + prefixIcon: Icon(Icons.person_outline)), + ), ), - onPressed: () { - setState(() { - _obscureText = !_obscureText; - }); - }, - ), - ), - ), - ), + const Padding( + padding: EdgeInsets.only(bottom: 5), + child: Align( + alignment: Alignment.topLeft, + child: Text('Email', + style: TextStyle( + fontSize: 18.0, color: Color(0xFF65676B))), + )), + Padding( + padding: EdgeInsets.only(bottom: 18), + child: TextFormField( + controller: controller.email, + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + hintText: 'Hello@gmail.com', + fillColor: Color.fromARGB(255, 239, 239, 239), + filled: true, + prefixIcon: Icon(Icons.email_outlined)), + ), + ), + const Padding( + padding: EdgeInsets.only(bottom: 5), + child: Align( + alignment: Alignment.topLeft, + child: Text('Password', + style: TextStyle( + fontSize: 18.0, color: Color(0xFF65676B))), + )), + Padding( + padding: EdgeInsets.only(bottom: 25), + child: TextFormField( + controller: controller.password, + obscureText: _obscureText, + decoration: InputDecoration( + enabledBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + focusedBorder: OutlineInputBorder( + borderSide: + BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + hintText: 'ContraseƱa', + fillColor: Color.fromARGB(255, 239, 239, 239), + filled: true, + prefixIcon: Icon(Icons.lock_outline), + suffixIcon: IconButton( + icon: Icon( + _obscureText + ? Icons.visibility_off + : Icons.visibility, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _obscureText = !_obscureText; + }); + }, + ), + ), + ), + ), + ], + )), Padding( padding: const EdgeInsets.only(bottom: 25), child: Center( child: ElevatedButton( - onPressed: () {}, + onPressed: () { + if (_formKey.currentState!.validate()) { + RegisterController.instance.registerUser( + controller.email.text.trim(), + controller.password.text.trim()); + } + }, child: Text( 'Registrarme', style: TextStyle( diff --git a/pubspec.lock b/pubspec.lock index a341140..c4c535f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -90,7 +90,7 @@ packages: source: hosted version: "5.2.10" firebase_core: - dependency: transitive + dependency: "direct main" description: name: firebase_core sha256: "75f747cafd7cbd6c00b908e3a7aa59fc31593d46ba8165d9ee8a79e69464a394" @@ -144,6 +144,14 @@ packages: url: "https://pub.dev" source: hosted version: "10.4.0" + get: + dependency: "direct main" + description: + name: get + sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a" + url: "https://pub.dev" + source: hosted + version: "4.6.5" google_identity_services_web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0bc5f0d..e00f7e4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,8 +38,10 @@ dependencies: # Google Sign In firebase_auth: ^4.3.0 + firebase_core: ^2.8.0 google_sign_in: ^6.0.2 provider: ^6.0.5 + get: ^4.6.5 font_awesome_flutter: ^10.4.0 dev_dependencies: