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/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/primary_btn.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'; import 'package:provider/provider.dart'; import 'package:responsive_builder/responsive_builder.dart'; class LoginEmailScreen extends StatefulWidget { const LoginEmailScreen({super.key}); @override State createState() => _LoginEmailScreenState(); } class _LoginEmailScreenState extends State { bool _obscureText = true; final controller = Get.put(LoginEmailController()); final _formKey = GlobalKey(); SettingModel? settings; @override void initState() { super.initState(); if (settings == null) { SettingModel.getSettings().then( (SettingModel value) => setState(() { settings = value; }), ); } } @override Widget build(BuildContext context) { return ScreenTypeLayout.builder( mobile: (BuildContext context) => _mobileView(context), tablet: (BuildContext context) => _mobileView(context), desktop: (BuildContext context) => _desktopView(context), ); } 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))), ), 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( '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, ), ), ], ), ) : 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() ], ), ), ), ], ), ), ), ); } Widget _desktopView(BuildContext context) { double height = MediaQuery.of(context).size.height; double width = MediaQuery.of(context).size.width; return Scaffold( backgroundColor: const Color(0xFFD6F4FF), body: SizedBox( height: height, width: width, child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( child: SizedBox( height: height, child: const Center( child: Image( image: AssetImage('images/logo_prosapp.png'), ), ), ), ), Expanded( child: Container( padding: EdgeInsets.symmetric(horizontal: width * 0.07), color: Colors.white, height: height, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ IconButton( icon: const Icon( Icons.arrow_back, size: 30, ), onPressed: () { Navigator.pop(context); }, ), SizedBox(width: width * 0.01), 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), 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))), )), 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))), ), ), Padding( padding: const EdgeInsets.only(bottom: 50), child: 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', 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.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() ]), ), ), ], ), ), ), ], ), ), ); } } class FormEmail extends StatelessWidget { const FormEmail({ super.key, required this.controller, }); final LoginEmailController controller; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(bottom: 20), 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, ), ), ), ); } } class PaddingButtomBottom extends StatelessWidget { const PaddingButtomBottom({ super.key, required GlobalKey formKey, required this.controller, }) : _formKey = formKey; final GlobalKey _formKey; final LoginEmailController controller; @override Widget build(BuildContext context) { 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', )), ); } } class RichTxtBottom extends StatelessWidget { const RichTxtBottom({ super.key, }); @override Widget build(BuildContext context) { return RichText( text: TextSpan( style: const TextStyle( fontSize: 16.0, color: Color(0xFF65676B), fontFamily: 'Poppins', ), children: [ const TextSpan(text: '¿No estás registrado? '), WidgetSpan( child: GestureDetector( onTap: () { Navigator.pushReplacementNamed(context, '/register'); }, child: const Text( 'Registrarse', style: TextStyle( fontSize: 16.0, color: Color(0xFF2BA4EC), fontWeight: FontWeight.w600, ), ), ), ), ], ), ); } }