From 043c3c580c0c330e119a2e5adeaf93c088cbacaf Mon Sep 17 00:00:00 2001 From: Felipe Date: Tue, 14 Nov 2023 12:37:09 -0500 Subject: [PATCH] update --- lib/src/components/bottom_sheet.dart | 51 ++ lib/src/presentation/screens/login/login.dart | 10 +- .../screens/login/login_email.dart | 433 +++++------ .../screens/register/register.dart | 713 ++++++++---------- .../widgets/shared/primary_button.dart | 48 +- pubspec.lock | 8 + pubspec.yaml | 1 + 7 files changed, 620 insertions(+), 644 deletions(-) diff --git a/lib/src/components/bottom_sheet.dart b/lib/src/components/bottom_sheet.dart index 9428348..73a19a0 100644 --- a/lib/src/components/bottom_sheet.dart +++ b/lib/src/components/bottom_sheet.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:animate_do/animate_do.dart'; class BottomSheetExpanded extends StatelessWidget { final List children; @@ -12,6 +13,56 @@ class BottomSheetExpanded extends StatelessWidget { @override Widget build(BuildContext context) { + return Scaffold( + body: Container( + width: double.infinity, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + colors: [ + Color.fromARGB(255, 87, 210, 255), + Color.fromARGB(255, 137, 224, 255), + Color(0xFFD6F4FF), + ], + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 50), + Center( + child: FadeInLeft( + duration: const Duration(milliseconds: 1000), + child: const Image( + image: AssetImage('images/logo_prosapp.png'), + ), + ), + ), + const SizedBox(height: 30), + Expanded( + child: FadeInUpBig( + duration: const Duration(milliseconds: 1000), + child: Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(60), + topRight: Radius.circular(60))), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: horizontalPadding, + vertical: 15, + ), + child: Column(children: children), + ), + ), + ), + ) + ], + ), + ), + ); + return SafeArea( child: Scaffold( backgroundColor: const Color(0xFFD6F4FF), diff --git a/lib/src/presentation/screens/login/login.dart b/lib/src/presentation/screens/login/login.dart index 177aa94..df64b66 100644 --- a/lib/src/presentation/screens/login/login.dart +++ b/lib/src/presentation/screens/login/login.dart @@ -5,7 +5,7 @@ import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:intl_phone_field/intl_phone_field.dart'; import 'package:prosappco/src/components/bottom_sheet.dart'; -import 'package:prosappco/src/components/primary_btn.dart'; +import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart'; import 'package:prosappco/src/controllers/phone_auth_controller.dart'; import 'package:prosappco/src/models/setting_model.dart'; import 'package:prosappco/src/providers/user_provider.dart'; @@ -180,7 +180,7 @@ class _LoginScreenState extends State { ], ), ), - PrimaryButtom( + PrimaryButton( onPressed: () async { if (_formKey.currentState!.validate()) { PhoneAuthController.instance.phoneAuthentication( @@ -196,8 +196,8 @@ class _LoginScreenState extends State { .initUserProvider(); } }, + text: 'Enviar código', isEnabled: _isChecked, - label: 'Enviar código', ), const SizedBox(height: 20), GestureBottom(clearPhoneNumber: _clearPhoneNumber), @@ -353,7 +353,7 @@ class _LoginScreenState extends State { ], ), ), - PrimaryButtom( + PrimaryButton( onPressed: () async { if (_formKey.currentState!.validate()) { PhoneAuthController.instance.phoneAuthentication( @@ -369,8 +369,8 @@ class _LoginScreenState extends State { .initUserProvider(); } }, + text: 'Enviar código', isEnabled: _isChecked, - label: 'Enviar código', ), const SizedBox(height: 20), GestureBottom(clearPhoneNumber: _clearPhoneNumber), diff --git a/lib/src/presentation/screens/login/login_email.dart b/lib/src/presentation/screens/login/login_email.dart index d46a247..3bbabc4 100644 --- a/lib/src/presentation/screens/login/login_email.dart +++ b/lib/src/presentation/screens/login/login_email.dart @@ -3,7 +3,8 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; -import 'package:prosappco/src/components/primary_btn.dart'; +import 'package:prosappco/src/components/bottom_sheet.dart'; +import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart'; import 'package:prosappco/src/controllers/login_email_controller.dart'; import 'package:prosappco/src/models/setting_model.dart'; import 'package:prosappco/src/providers/user_provider.dart'; @@ -47,230 +48,197 @@ class _LoginEmailScreenState extends State { Widget _mobileView(BuildContext context) { bool isIOS = Theme.of(context).platform == TargetPlatform.iOS; - return SafeArea( - child: Scaffold( - backgroundColor: const Color(0xFFD6F4FF), - body: SingleChildScrollView( - reverse: true, - child: Stack( - children: [ - Container( - margin: const EdgeInsets.only(top: 130), - width: double.infinity, - height: 700, - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topRight: Radius.circular(50), - topLeft: Radius.circular(50))), + return BottomSheetExpanded( + horizontalPadding: 10, + children: [ + Row( + children: [ + IconButton( + icon: const Icon( + Icons.arrow_back, + size: 30, ), - Container( - margin: const EdgeInsets.only(top: 20, left: 30), - child: const Image( - image: AssetImage('images/logo_prosapp.png'), - width: 180, - height: 100, - ), + onPressed: () { + Navigator.pop(context); + }, + ), + const Text( + 'Iniciar sesión', + style: TextStyle( + color: Color(0xFF262626), + fontSize: 38.0, + fontWeight: FontWeight.bold, ), - Container( - padding: - const EdgeInsets.symmetric(horizontal: 0, vertical: 20), - margin: const EdgeInsets.only( - top: 125, - left: 25, - ), - child: Row( - children: [ - IconButton( - icon: const Icon( - Icons.arrow_back, - size: 30, - ), - onPressed: () { - Navigator.pop(context); - }, - ), - const Text( - 'Iniciar sesión', - style: TextStyle( - color: Color(0xFF262626), - fontSize: 38.0, - fontWeight: FontWeight.bold, - ), - textAlign: TextAlign.right, - ), - ], - ), - ), - 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: [ - !isIOS && !kIsWeb && settings?.google == true - ? Padding( - padding: const EdgeInsets.only(bottom: 20), - child: ElevatedButton( - onPressed: () async { - await AuthenticationRepository.instance - .signInWithGoogle() - .then((value) => { - Provider.of(context, - listen: false) - .initUserProvider() - }); - }, - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF2BA4EC), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50), - ), - elevation: 0, - minimumSize: const Size(230, 60), - ), - child: const Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Entra con Google ', - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 18, - ), - ), - SizedBox(width: 5), - FaIcon(FontAwesomeIcons.google), - ], - )), - ) - : const SizedBox(), - !isIOS && !kIsWeb && settings?.google == true - ? const 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, - ), - ), - ], + textAlign: TextAlign.right, + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25), + child: Form( + key: _formKey, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 20), + child: Column( + children: [ + !isIOS && !kIsWeb && settings?.google == true + ? Padding( + padding: const EdgeInsets.only(bottom: 20), + child: ElevatedButton( + onPressed: () async { + await AuthenticationRepository.instance + .signInWithGoogle() + .then((value) => { + Provider.of(context, + listen: false) + .initUserProvider() + }); + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF2BA4EC), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), + ), + elevation: 0, + minimumSize: const Size(230, 60), ), - ) - : const SizedBox(), - const Padding( - padding: EdgeInsets.only(bottom: 5), - child: Align( - alignment: Alignment.topLeft, - child: Text('Email', - style: TextStyle( - fontSize: 18.0, color: Color(0xFF65676B))), - ), - ), - FormEmail(controller: controller), - const Padding( - padding: EdgeInsets.only(bottom: 5), - child: Align( - alignment: Alignment.topLeft, - child: Text('Password', - style: TextStyle( - fontSize: 18.0, color: Color(0xFF65676B))), - ), - ), - TextFormField( - controller: controller.password, - obscureText: _obscureText, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Por favor, ingresa una contraseña'; - } - return null; - }, - decoration: InputDecoration( - enabledBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), + child: const Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Entra con Google ', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + SizedBox(width: 5), + FaIcon(FontAwesomeIcons.google), + ], )), - focusedBorder: const OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - border: const OutlineInputBorder( - borderSide: BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - errorBorder: const OutlineInputBorder( - borderSide: BorderSide( - color: Color.fromARGB(255, 184, 0, 0)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - hintText: 'Contraseña', - fillColor: const Color.fromARGB(255, 239, 239, 239), - filled: true, - prefixIcon: const Icon(Icons.lock_outline), - suffixIcon: IconButton( - icon: Icon( - _obscureText - ? Icons.visibility - : Icons.visibility_off, - color: Colors.grey, - ), - onPressed: () { - setState(() { - _obscureText = !_obscureText; - }); - }, + ) + : const SizedBox(), + !isIOS && !kIsWeb && settings?.google == true + ? const 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, + ), + ), + ], ), - hintStyle: const TextStyle( - color: Colors.grey, - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 20), - child: TextButton( - onPressed: () { - Navigator.pushNamed(context, '/resetpassword'); - }, - child: const Text( - 'Olvidé la contraseña', - style: TextStyle( - color: Colors.blue, - ), - ), - ), - ), - PaddingButtomBottom( - formKey: _formKey, controller: controller), - const RichTxtBottom() - ], + ) + : const SizedBox(), + const Padding( + padding: EdgeInsets.only(bottom: 5), + child: Align( + alignment: Alignment.topLeft, + child: Text('Email', + style: TextStyle( + fontSize: 18.0, color: Color(0xFF65676B))), + ), ), - ), + FormEmail(controller: controller), + const Padding( + padding: EdgeInsets.only(bottom: 5), + child: Align( + alignment: Alignment.topLeft, + child: Text('Password', + style: TextStyle( + fontSize: 18.0, color: Color(0xFF65676B))), + ), + ), + TextFormField( + controller: controller.password, + obscureText: _obscureText, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor, ingresa una contraseña'; + } + return null; + }, + decoration: InputDecoration( + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + border: const OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + errorBorder: const OutlineInputBorder( + borderSide: + BorderSide(color: Color.fromARGB(255, 184, 0, 0)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + hintText: 'Contraseña', + fillColor: const Color.fromARGB(255, 239, 239, 239), + filled: true, + prefixIcon: const Icon(Icons.lock_outline), + suffixIcon: IconButton( + icon: Icon( + _obscureText + ? Icons.visibility + : Icons.visibility_off, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _obscureText = !_obscureText; + }); + }, + ), + hintStyle: const TextStyle( + color: Colors.grey, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: TextButton( + onPressed: () { + Navigator.pushNamed(context, '/resetpassword'); + }, + child: const Text( + 'Olvidé la contraseña', + style: TextStyle( + color: Colors.blue, + ), + ), + ), + ), + PaddingButtomBottom( + formKey: _formKey, controller: controller), + const RichTxtBottom() + ], ), - ], + ), ), ), - ), + ], ); } @@ -519,22 +487,23 @@ class PaddingButtomBottom extends StatelessWidget { return Padding( padding: const EdgeInsets.only(bottom: 40), child: Center( - child: PrimaryButtom( - onPressed: () { - if (_formKey.currentState!.validate()) { - LoginEmailController.instance - .loginUser( - controller.email.text.trim(), - controller.password.text.trim(), - ) - .then((value) { - Provider.of(context, listen: false) - .initUserProvider(); - }); - } - }, - label: 'Iniciar', - )), + child: PrimaryButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + LoginEmailController.instance + .loginUser( + controller.email.text.trim(), + controller.password.text.trim(), + ) + .then((value) { + Provider.of(context, listen: false) + .initUserProvider(); + }); + } + }, + text: 'Iniciar', + ), + ), ); } } diff --git a/lib/src/presentation/screens/register/register.dart b/lib/src/presentation/screens/register/register.dart index a931f5e..61b7349 100644 --- a/lib/src/presentation/screens/register/register.dart +++ b/lib/src/presentation/screens/register/register.dart @@ -1,16 +1,15 @@ -import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.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/authentication/authentication_repository.dart'; -import 'package:prosappco/src/components/primary_btn.dart'; +import 'package:prosappco/src/components/bottom_sheet.dart'; +import 'package:prosappco/src/components/column_padding.dart'; +import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart'; import 'package:prosappco/src/controllers/register_controller.dart'; import 'package:prosappco/src/models/setting_model.dart'; import 'package:prosappco/src/providers/user_provider.dart'; -import 'package:prosappco/src/presentation/screens/login/login.dart'; import 'package:prosappco/src/presentation/screens/web_view.dart'; import 'package:provider/provider.dart'; import 'package:responsive_builder/responsive_builder.dart'; @@ -62,371 +61,316 @@ class _RegisterScreenState extends State { Widget _mobileView(BuildContext context) { bool isIOS = Theme.of(context).platform == TargetPlatform.iOS; - return SafeArea( - child: Scaffold( - backgroundColor: const Color(0xFFD6F4FF), - body: GestureDetector( - onTap: () => FocusScope.of(context).unfocus(), - child: SingleChildScrollView( - reverse: true, - child: Stack( - children: [ - Container( - margin: const EdgeInsets.only(top: 130), - width: double.infinity, - height: 700, - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topRight: Radius.circular(50), - topLeft: Radius.circular(50))), - ), - Container( - margin: const EdgeInsets.only(top: 20, left: 30), - child: const Image( - image: AssetImage('images/logo_prosapp.png'), - width: 180, - height: 100, - ), - ), - Container( - padding: - const EdgeInsets.symmetric(horizontal: 0, vertical: 20), - margin: const EdgeInsets.only( - top: 125, - left: 25, - ), - child: Row( - children: [ - IconButton( - icon: const Icon( - Icons.arrow_back, - size: 30, - ), - onPressed: () { - Navigator.pop(context); - }, - ), - const Text( - 'Registro', - style: TextStyle( - color: Color(0xFF262626), - fontSize: 38.0, - fontWeight: FontWeight.bold, - ), - textAlign: TextAlign.right, - ), - ], - ), - ), - Container( - padding: - const EdgeInsets.symmetric(horizontal: 0, vertical: 20), - margin: const EdgeInsets.only(top: 200, left: 50, right: 50), - child: Column( - children: [ - !isIOS && !kIsWeb && settings?.google == true - ? Padding( - padding: const EdgeInsets.only(bottom: 20), - child: ElevatedButton( - onPressed: () async { - await AuthenticationRepository.instance - .signInWithGoogle(); - }, - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF2BA4EC), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50), - ), - elevation: 0, - minimumSize: const Size(230, 60), - ), - child: const 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 SizedBox(), - !isIOS && !kIsWeb && settings?.google == true - ? const Padding( - padding: EdgeInsets.symmetric(vertical: 0), - 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 SizedBox(), - Form( - key: _formKey, - child: Column( - children: [ - 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: const EdgeInsets.only(bottom: 18), - child: TextFormField( - controller: controller.email, - validator: (String? value) { - if (value == null || value.isEmpty) { - return 'Por favor ingresa un email'; - } - final RegExp emailRegExp = RegExp( - r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); - if (!emailRegExp.hasMatch(value)) { - return 'Por favor ingresa un email válido'; - } - return null; - }, - decoration: const InputDecoration( - border: OutlineInputBorder( - borderSide: - BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - 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), - )), - errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: - Color.fromARGB(255, 184, 0, 0)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - hintText: 'Hello@gmail.com', - fillColor: Color.fromARGB(255, 239, 239, 239), - filled: true, - prefixIcon: Icon(Icons.email_outlined), - hintStyle: TextStyle( - color: Colors.grey, - ), - ), - ), - ), - 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: const EdgeInsets.only(bottom: 25), - child: TextFormField( - controller: controller.password, - obscureText: _obscureText, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Por favor ingresa una contraseña'; - } - if (value.length <= 6) { - return 'Contraseña muy corta'; - } - return null; - }, - decoration: InputDecoration( - errorBorder: const OutlineInputBorder( - borderSide: BorderSide( - color: - Color.fromARGB(255, 184, 0, 0)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - enabledBorder: const OutlineInputBorder( - borderSide: - BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - border: const OutlineInputBorder( - borderSide: - BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - focusedBorder: const OutlineInputBorder( - borderSide: - BorderSide(color: Color(0xFFECECEC)), - borderRadius: BorderRadius.all( - Radius.circular(50), - )), - hintText: 'Contraseña', - hintStyle: const TextStyle( - color: Colors.grey, - ), - fillColor: - const Color.fromARGB(255, 239, 239, 239), - filled: true, - prefixIcon: const Icon(Icons.lock_outline), - suffixIcon: IconButton( - icon: Icon( - _obscureText - ? Icons.visibility - : Icons.visibility_off, - color: Colors.grey, - ), - onPressed: () { - setState(() { - _obscureText = !_obscureText; - }); - }, - ), - ), - ), - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.only(bottom: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment - .center, // Centra horizontalmente - children: [ - Checkbox( - value: _isChecked, - onChanged: (value) { - setState(() { - _isChecked = value!; - }); - }, - ), - GestureDetector( - onTap: () { - if (kIsWeb) { - _launchURL( - settings?.terminosCondiciones ?? ''); - } else { - Navigator.push( - context, - CupertinoPageRoute( - builder: (BuildContext context) { - return WebViewScreen( - label: 'Políticas de privacidad', - link: settings?.terminosCondiciones ?? - '', - ); - }, - ), - ); - } - }, - child: const Text( - 'Acepto los términos y condiciones.', - style: TextStyle( - color: Color(0xFF65676B), - decoration: TextDecoration.underline, - ), - ), - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.only(bottom: 25), - child: Center( - child: PrimaryButtom( - onPressed: () { - if (_formKey.currentState!.validate()) { - RegisterController.instance - .registerUser( - controller.email.text.trim(), - controller.password.text.trim(), - ) - .then((value) => Provider.of( - context, - listen: false) - .initUserProvider()); - } - }, - label: 'Registrarme', - isEnabled: _isChecked, - ), - ), - ), - RichText( - text: TextSpan( - style: const TextStyle( - fontSize: 16.0, - color: Color(0xFF65676B), - fontFamily: 'Poppins', - ), - children: [ - const TextSpan(text: 'Ya estas registrado? '), - WidgetSpan( - child: GestureDetector( - onTap: () { - Navigator.pushReplacementNamed( - context, '/login'); - }, - child: const Text( - 'Iniciar Sesión', - style: TextStyle( - fontSize: 16.0, - color: Color(0xFF2BA4EC), - fontWeight: FontWeight.w600, - ), - ), - ), - ), - ], - ), - ) - ], - ), - ), - ], + return BottomSheetExpanded( + horizontalPadding: 10, + children: [ + Row( + children: [ + IconButton( + icon: const Icon( + Icons.arrow_back, + size: 30, + ), + onPressed: () { + Navigator.pop(context); + }, ), - ), + const Text( + 'Registro', + style: TextStyle( + color: Color(0xFF262626), + fontSize: 38.0, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.right, + ), + ], ), - ), + ColumnPadding( + alineacion: MainAxisAlignment.start, + padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20), + children: [ + !isIOS && !kIsWeb && settings?.google == true + ? Padding( + padding: const EdgeInsets.only(bottom: 20), + child: ElevatedButton( + onPressed: () async { + await AuthenticationRepository.instance + .signInWithGoogle(); + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF2BA4EC), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), + ), + elevation: 0, + minimumSize: const Size(230, 60), + ), + child: const 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 SizedBox(), + !isIOS && !kIsWeb && settings?.google == true + ? const Padding( + padding: EdgeInsets.symmetric(vertical: 0), + 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 SizedBox(), + Form( + key: _formKey, + child: Column( + children: [ + 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: const EdgeInsets.only(bottom: 18), + child: TextFormField( + controller: controller.email, + validator: (String? value) { + if (value == null || value.isEmpty) { + return 'Por favor ingresa un email'; + } + final RegExp emailRegExp = + RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); + if (!emailRegExp.hasMatch(value)) { + return 'Por favor ingresa un email válido'; + } + return null; + }, + decoration: const InputDecoration( + border: OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + 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), + )), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Color.fromARGB(255, 184, 0, 0)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + hintText: 'Hello@gmail.com', + fillColor: Color.fromARGB(255, 239, 239, 239), + filled: true, + prefixIcon: Icon(Icons.email_outlined), + hintStyle: TextStyle( + color: Colors.grey, + ), + ), + ), + ), + 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: const EdgeInsets.only(bottom: 25), + child: TextFormField( + controller: controller.password, + obscureText: _obscureText, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Por favor ingresa una contraseña'; + } + if (value.length <= 6) { + return 'Contraseña muy corta'; + } + return null; + }, + decoration: InputDecoration( + errorBorder: const OutlineInputBorder( + borderSide: BorderSide( + color: Color.fromARGB(255, 184, 0, 0)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + border: const OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Color(0xFFECECEC)), + borderRadius: BorderRadius.all( + Radius.circular(50), + )), + hintText: 'Contraseña', + hintStyle: const TextStyle( + color: Colors.grey, + ), + fillColor: const Color.fromARGB(255, 239, 239, 239), + filled: true, + prefixIcon: const Icon(Icons.lock_outline), + suffixIcon: IconButton( + icon: Icon( + _obscureText + ? Icons.visibility + : Icons.visibility_off, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _obscureText = !_obscureText; + }); + }, + ), + ), + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 20), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, // Centra horizontalmente + children: [ + Checkbox( + value: _isChecked, + onChanged: (value) { + setState(() { + _isChecked = value!; + }); + }, + ), + GestureDetector( + onTap: () { + if (kIsWeb) { + _launchURL(settings?.terminosCondiciones ?? ''); + } else { + Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return WebViewScreen( + label: 'Políticas de privacidad', + link: settings?.terminosCondiciones ?? '', + ); + }, + ), + ); + } + }, + child: const Text( + 'Acepto los términos y condiciones.', + style: TextStyle( + color: Color(0xFF65676B), + decoration: TextDecoration.underline, + ), + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 25), + child: Center( + child: PrimaryButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + RegisterController.instance + .registerUser( + controller.email.text.trim(), + controller.password.text.trim(), + ) + .then((value) => + Provider.of(context, listen: false) + .initUserProvider()); + } + }, + text: 'Registrarme', + isEnabled: _isChecked, + ), + ), + ), + RichText( + text: TextSpan( + style: const TextStyle( + fontSize: 16.0, + color: Color(0xFF65676B), + fontFamily: 'Poppins', + ), + children: [ + const TextSpan(text: 'Ya estas registrado? '), + WidgetSpan( + child: GestureDetector( + onTap: () { + Navigator.pushReplacementNamed(context, '/login'); + }, + child: const Text( + 'Iniciar Sesión', + style: TextStyle( + fontSize: 16.0, + color: Color(0xFF2BA4EC), + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ], + ), + ) + ], + ), + ], ); } @@ -684,24 +628,23 @@ class _RegisterScreenState extends State { Padding( padding: const EdgeInsets.only(bottom: 25), child: Center( - child: PrimaryButtom( - onPressed: () { - if (_formKey.currentState!.validate()) { - RegisterController.instance - .registerUser( - controller.email.text.trim(), - controller.password.text.trim(), - ) - .then((value) => - Provider.of(context, - listen: false) - .initUserProvider()); - } - }, - isEnabled: _isChecked, - label: 'Registrarme', - ), - ), + child: PrimaryButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + RegisterController.instance + .registerUser( + controller.email.text.trim(), + controller.password.text.trim(), + ) + .then((value) => + Provider.of(context, + listen: false) + .initUserProvider()); + } + }, + text: 'Registrarme', + isEnabled: _isChecked, + )), ), RichText( text: TextSpan( diff --git a/lib/src/presentation/widgets/shared/primary_button.dart b/lib/src/presentation/widgets/shared/primary_button.dart index b134c5f..2ecbea1 100644 --- a/lib/src/presentation/widgets/shared/primary_button.dart +++ b/lib/src/presentation/widgets/shared/primary_button.dart @@ -5,33 +5,37 @@ class PrimaryButton extends StatelessWidget { final String text; final double? minWidth; final double? minHeight; + final bool isEnabled; - const PrimaryButton( - {super.key, - required this.onPressed, - required this.text, - this.minWidth = 200, - this.minHeight = 50}); + const PrimaryButton({ + super.key, + required this.onPressed, + required this.text, + this.minWidth = 200, + this.minHeight = 50, + this.isEnabled = true, + }); @override Widget build(BuildContext context) { return ElevatedButton( - onPressed: onPressed, - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF2BA4EC), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50), - ), - elevation: 0, - minimumSize: Size(minWidth!, minHeight!), + onPressed: isEnabled ? onPressed : null, + style: ElevatedButton.styleFrom( + backgroundColor: isEnabled ? const Color(0xFF2BA4EC) : Colors.grey, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), ), - child: Text( - text, - style: const TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 17, - ), - )); + elevation: 0, + minimumSize: Size(minWidth!, minHeight!), + ), + child: Text( + text, + style: TextStyle( + color: isEnabled ? Colors.white : Colors.black, + fontWeight: FontWeight.bold, + fontSize: 17, + ), + ), + ); } } diff --git a/pubspec.lock b/pubspec.lock index e668bb8..ba8a8fe 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -25,6 +25,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.13.0" + animate_do: + dependency: "direct main" + description: + name: animate_do + sha256: "9aeacc1a7238f971c039bdf45d13c628be554a242e0251c4ddda09d19a1a923f" + url: "https://pub.dev" + source: hosted + version: "3.0.2" animated_splash_screen: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 478a3ff..d4c1f04 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -68,6 +68,7 @@ dependencies: universal_html: ^2.2.3 firebase_messaging: ^14.6.3 animated_splash_screen: ^1.3.0 + animate_do: ^3.0.2 dev_dependencies: flutter_test: