diff --git a/android/app/build.gradle b/android/app/build.gradle index 44f49bc..f900c60 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -48,7 +48,7 @@ android { applicationId "com.example.prosappco" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion "21".toInteger() targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/lib/src/authentication/authentication_repository.dart b/lib/src/authentication/authentication_repository.dart index d77d266..64eba1a 100644 --- a/lib/src/authentication/authentication_repository.dart +++ b/lib/src/authentication/authentication_repository.dart @@ -1,4 +1,6 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:prosappco/src/authentication/exceptions/register_failed.dart'; @@ -11,7 +13,9 @@ class AuthenticationRepository extends GetxController { //Variables final _auth = FirebaseAuth.instance; late final Rx firebaseUser; + final firebase = FirebaseFirestore.instance; final GoogleSignIn googleSignIn = GoogleSignIn(); + // final _userRef = firebase var verificationId = ''.obs; @override @@ -60,8 +64,17 @@ class AuthenticationRepository extends GetxController { Future createUserWithEmailAndPassword( String email, String password) async { try { + // try { + // await firebase.collection('Users').doc().set({ + // "Email": email, + // "Password": password, + // }); + // } catch (e) { + // print('Error $e'); + // } await _auth.createUserWithEmailAndPassword( email: email, password: password); + firebaseUser.value != null ? Get.offAll(() => WelcomeScreen()) : Get.to(() => LoginScreen()); @@ -98,4 +111,50 @@ class AuthenticationRepository extends GetxController { } Future logout() async => _auth.signOut(); + + String? getCurrentUserPhone() { + final User? user = _auth.currentUser; + return user?.phoneNumber; + } + + String? getCurrentUserUid() { + final User? user = _auth.currentUser; + return user?.uid; + } + + Future addNameAndEmail( + uid, String name, String email, String city) async { + final usersCollection = FirebaseFirestore.instance.collection('users'); + await usersCollection.doc(uid).set({ + 'name': name, + 'email': email, + 'city': city, + }); + } + + Future getName(String uid) async { + String city = 'error'; + CollectionReference collectionUsers = + FirebaseFirestore.instance.collection('users'); + DocumentSnapshot snapshot = await collectionUsers.doc(uid).get(); + + final Map doc = snapshot.data() as Map; + if (doc['name'] != null) { + city = doc['name']; + } + return city; + } + + Future getCity(String uid) async { + String city = 'error'; + CollectionReference collectionUsers = + FirebaseFirestore.instance.collection('users'); + DocumentSnapshot snapshot = await collectionUsers.doc(uid).get(); + + final Map doc = snapshot.data() as Map; + if (doc['city'] != null) { + city = doc['city']; + } + return city; + } } diff --git a/lib/src/controllers/add_name_email_city.dart b/lib/src/controllers/add_name_email_city.dart new file mode 100644 index 0000000..13661f3 --- /dev/null +++ b/lib/src/controllers/add_name_email_city.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:prosappco/src/authentication/authentication_repository.dart'; + +class NameEmailCityController extends GetxController { + static NameEmailCityController get instance => Get.find(); + + final name = TextEditingController(); + final email = TextEditingController(); + final city = TextEditingController(); +} diff --git a/lib/src/controllers/login_email_controller.dart b/lib/src/controllers/login_email_controller.dart new file mode 100644 index 0000000..0130320 --- /dev/null +++ b/lib/src/controllers/login_email_controller.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:prosappco/src/authentication/authentication_repository.dart'; + +class LoginEmailController extends GetxController { + static LoginEmailController get instance => Get.find(); + + final email = TextEditingController(); + final password = TextEditingController(); +} diff --git a/lib/src/screens/login_email.dart b/lib/src/screens/login_email.dart index 0f4a863..0915dc8 100644 --- a/lib/src/screens/login_email.dart +++ b/lib/src/screens/login_email.dart @@ -1,7 +1,9 @@ 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/authentication/authentication_repository.dart'; +import 'package:prosappco/src/controllers/login_email_controller.dart'; import 'package:prosappco/src/screens/login.dart'; import 'package:prosappco/src/screens/welcome.dart'; import 'package:provider/provider.dart'; @@ -19,6 +21,8 @@ class LoginEmailScreen extends StatefulWidget { class _LoginEmailScreenState extends State { bool _obscureText = true; + final controller = Get.put(LoginEmailController()); + final _formKey = GlobalKey(); @override Widget build(BuildContext context) { @@ -75,76 +79,109 @@ class _LoginEmailScreenState extends State { ], ), ), - Container( - padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 20), - margin: const EdgeInsets.only(top: 210, left: 50, right: 50), - child: Column(children: [ - Padding( - padding: EdgeInsets.only(bottom: 20), - child: ElevatedButton( - onPressed: () async { - await AuthenticationRepository.instance - .signInWithGoogle(); - }, - style: ElevatedButton.styleFrom( - primary: Color(0xFF2BA4EC), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50), - ), - elevation: 0, - minimumSize: Size(230, 60), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Entrar con Google ', - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 18, - ), + Form( + key: _formKey, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 20), + margin: const EdgeInsets.only(top: 210, left: 50, right: 50), + child: Column(children: [ + Padding( + padding: EdgeInsets.only(bottom: 20), + child: ElevatedButton( + onPressed: () async { + await AuthenticationRepository.instance + .signInWithGoogle(); + }, + style: ElevatedButton.styleFrom( + primary: Color(0xFF2BA4EC), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), ), - SizedBox(width: 5), - FaIcon(FontAwesomeIcons.google), - ], - )), - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 5), - child: Row( - children: [ - Expanded( - child: Divider( - color: Colors.black38, - thickness: 1, + elevation: 0, + minimumSize: Size(230, 60), ), - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 10), - child: Text("ó"), - ), - Expanded( - child: Divider( - color: Colors.black38, - thickness: 1, - ), - ), - ], + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Entrar con Google ', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + SizedBox(width: 5), + FaIcon(FontAwesomeIcons.google), + ], + )), ), - ), - 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: 20), - child: TextField( - decoration: InputDecoration( + Padding( + padding: EdgeInsets.symmetric(vertical: 5), + child: Row( + children: [ + Expanded( + child: Divider( + color: Colors.black38, + thickness: 1, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Text("ó"), + ), + Expanded( + child: Divider( + color: Colors.black38, + thickness: 1, + ), + ), + ], + ), + ), + 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: 20), + 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)), + ), + ), + 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: 50), + child: TextFormField( + controller: controller.password, + obscureText: _obscureText, + decoration: InputDecoration( enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0xFFECECEC)), borderRadius: BorderRadius.all( @@ -155,108 +192,87 @@ class _LoginEmailScreenState extends State { borderRadius: BorderRadius.all( Radius.circular(50), )), - hintText: 'Hello@gmail.com', + hintText: 'Contraseña', 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: 50), - 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, - ), - onPressed: () { - setState(() { - _obscureText = !_obscureText; - }); - }, - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.only(bottom: 40), - child: Center( - child: ElevatedButton( - onPressed: () {}, - child: Text( - 'Iniciar', - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 18, - ), - ), - style: ElevatedButton.styleFrom( - primary: Color(0xFF2BA4EC), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50), - ), - elevation: 0, - minimumSize: Size(230, 60), - ), - )), - ), - RichText( - text: TextSpan( - style: TextStyle( - fontSize: 16.0, - color: Color(0xFF65676B), - fontFamily: 'Poppins', - ), - children: [ - TextSpan(text: 'No estas registrado? '), - WidgetSpan( - child: GestureDetector( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => RegisterScreen()), - ); + prefixIcon: Icon(Icons.lock_outline), + suffixIcon: IconButton( + icon: Icon( + _obscureText + ? Icons.visibility_off + : Icons.visibility, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _obscureText = !_obscureText; + }); }, - child: Text( - 'Registrarse', - style: TextStyle( - fontSize: 16.0, - color: Color(0xFF2BA4EC), - fontWeight: FontWeight.w600, + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 40), + child: Center( + child: ElevatedButton( + onPressed: () { + // controller.validateData( + // context, + // controller.email.text.trim(), + // controller.password.text.trim()); + }, + child: Text( + 'Iniciar', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + style: ElevatedButton.styleFrom( + primary: Color(0xFF2BA4EC), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), + ), + elevation: 0, + minimumSize: Size(230, 60), + ), + )), + ), + RichText( + text: TextSpan( + style: TextStyle( + fontSize: 16.0, + color: Color(0xFF65676B), + fontFamily: 'Poppins', + ), + children: [ + TextSpan(text: 'No estas registrado? '), + WidgetSpan( + child: GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => RegisterScreen()), + ); + }, + child: Text( + 'Registrarse', + style: TextStyle( + fontSize: 16.0, + color: Color(0xFF2BA4EC), + fontWeight: FontWeight.w600, + ), ), ), ), - ), - ], - ), - ) - ]), + ], + ), + ) + ]), + ), ), ], ), diff --git a/lib/src/screens/welcome.dart b/lib/src/screens/welcome.dart index 55e1322..72c01bb 100644 --- a/lib/src/screens/welcome.dart +++ b/lib/src/screens/welcome.dart @@ -1,5 +1,9 @@ +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:prosappco/src/controllers/add_name_email_city.dart'; class WelcomeScreen extends StatefulWidget { const WelcomeScreen({super.key}); @@ -9,8 +13,36 @@ class WelcomeScreen extends StatefulWidget { } class _WelcomeScreenState extends State { + final uid = AuthenticationRepository.instance.getCurrentUserUid(); + final _formKey = GlobalKey(); + final controller = Get.put(NameEmailCityController()); + var _nombre = 'Cargando...'; + var _ciudad = '...'; + + @override + void initState() { + super.initState(); + if (_nombre == 'Cargando...') { + AuthenticationRepository.instance + .getName(uid.toString()) + .then((String s) => setState(() { + _nombre = s; + })); + } + if (_ciudad == '...') { + AuthenticationRepository.instance + .getCity(uid.toString()) + .then((String s) => setState(() { + _ciudad = s; + })); + } + } + @override Widget build(BuildContext context) { + String name = _nombre.toString(); + String city = _ciudad.toString(); + return SafeArea( child: Scaffold( drawer: Drawer( @@ -20,15 +52,73 @@ class _WelcomeScreenState extends State { color: Colors.white, child: Column( children: [ + Padding( + padding: const EdgeInsets.only(top: 20, bottom: 20), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 20, right: 20), + child: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Color(0xFF2BA4EC), + borderRadius: BorderRadius.circular(50), + ), + child: Icon( + Icons.person, + size: 50, + color: Colors.white, + ), + ), + ), + Column( + children: [ + Text( + '$name', + style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 12), + ), + Text( + AuthenticationRepository.instance + .getCurrentUserPhone() + .toString(), + style: TextStyle(fontSize: 10), + ), + Text( + '$city', + style: TextStyle(fontSize: 10), + ), + ], + ), + SizedBox(width: 85), + Icon( + Icons.keyboard_arrow_right_outlined, + color: Color(0xFF2BA4EC), + ), + ], + ), + ), Container( - width: double.infinity, - height: 100, + height: 1.0, + color: Colors.grey.withOpacity(0.1), + ), + Container( + height: 2.0, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + spreadRadius: 1, + blurRadius: 2, + offset: Offset(0, 1), + ), + ], + ), ), Container( - margin: EdgeInsets.only(top: 30), padding: EdgeInsets.all(20), width: double.infinity, - color: Colors.grey[100], child: Row( children: [ Icon(Icons.history), @@ -40,7 +130,6 @@ class _WelcomeScreenState extends State { Container( padding: EdgeInsets.all(20), width: double.infinity, - color: Colors.grey[100], child: Row( children: [ Icon(Icons.person_outline), @@ -52,7 +141,6 @@ class _WelcomeScreenState extends State { Container( padding: EdgeInsets.all(20), width: double.infinity, - color: Colors.grey[100], child: Row( children: [ Icon(Icons.construction_outlined), @@ -66,7 +154,6 @@ class _WelcomeScreenState extends State { Container( padding: EdgeInsets.all(20), width: double.infinity, - color: Colors.grey[100], child: Row( children: [ Icon(Icons.question_mark_rounded), @@ -78,7 +165,6 @@ class _WelcomeScreenState extends State { Container( padding: EdgeInsets.all(20), width: double.infinity, - color: Colors.grey[100], child: Row( children: [ Icon(Icons.messenger_outline), @@ -254,6 +340,24 @@ class _WelcomeScreenState extends State { ), ), ), + Container( + padding: const EdgeInsets.only(top: 370), + child: Form( + key: _formKey, + child: Column( + children: [ + TextField( + controller: controller.name, + ), + TextField( + controller: controller.email, + ), + TextField( + controller: controller.city, + ), + ], + )), + ), Container( padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 20), margin: const EdgeInsets.only(top: 280, left: 50, right: 50), @@ -262,7 +366,14 @@ class _WelcomeScreenState extends State { padding: const EdgeInsets.only(bottom: 40), child: Center( child: ElevatedButton( - onPressed: () {}, + onPressed: () { + AuthenticationRepository.instance.addNameAndEmail( + uid, + controller.name.text.trim(), + controller.email.text.trim(), + controller.city.text.trim(), + ); + }, child: Text( 'Solicitar un servicio', style: TextStyle( diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 7b9be20..804ef2f 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,10 +5,12 @@ import FlutterMacOS import Foundation +import cloud_firestore import firebase_auth import firebase_core func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 5b98fe5..d2f44e2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "330d7fcbb72624f5b6d374af8b059b0ef4ba96ba5b8987f874964a1287eb617d" + sha256: f175bc1414e4edf8c5b83372c98eeabecf8353f39c9da423c2cfdf1f1f508788 url: "https://pub.dev" source: hosted - version: "1.0.18" + version: "1.1.0" async: dependency: transitive description: @@ -41,6 +41,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: "3a2dba23d7d084a2d3c2dfd240d2122908cca40bab2d142f7e107f40df174ab5" + url: "https://pub.dev" + source: hosted + version: "4.5.0" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: "29349a0687bc31290ab81d1de2b1cdadb40d0ea3ab30d247323c6c5be0d4c6fc" + url: "https://pub.dev" + source: hosted + version: "5.12.0" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: bc1fbcd6287acedded1139c9b13cfd47e792d5198f130f98759464839ea510a7 + url: "https://pub.dev" + source: hosted + version: "3.4.0" collection: dependency: transitive description: @@ -93,26 +117,26 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "75f747cafd7cbd6c00b908e3a7aa59fc31593d46ba8165d9ee8a79e69464a394" + sha256: ed611fb8e67e43ecc7956f242cecca383d87cf71aace27287aa5dd4bdba4ac07 url: "https://pub.dev" source: hosted - version: "2.8.0" + version: "2.9.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "5615b30c36f55b2777d0533771deda7e5730e769e5d3cb7fda79e9bed86cfa55" + sha256: "0df0a064ab0cad7f8836291ca6f3272edd7b83ad5b3540478ee46a0849d8022b" url: "https://pub.dev" source: hosted - version: "4.5.3" + version: "4.6.0" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: "0c1cf1f1022d2245ac117443bb95207952ca770281524d2908e323bc063fb8ff" + sha256: "347351a8f0518f3343d79a9a0690fa67ad232fc32e2ea270677791949eac792b" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 6846fb0..95a1cab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,7 @@ dependencies: font_awesome_flutter: ^10.4.0 flutter_otp_text_field: ^1.1.1 intl_phone_field: ^3.1.0 + cloud_firestore: ^4.5.0 dev_dependencies: flutter_test: