import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:generp/Notifiers/loginNotifier.dart'; import 'package:provider/provider.dart'; import 'package:share_plus/share_plus.dart'; import 'package:super_tooltip/super_tooltip.dart'; import '../Utils/app_colors.dart'; import '../Utils/commonServices.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override State createState() => _LoginScreenState(); } class _LoginScreenState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late ScrollController _scrollController; late SuperTooltipController tooltipcontroller; final List logos = [ 'assets/images/logo_1.png', 'assets/images/logo_2.png', 'assets/images/logo_3.png', 'assets/images/logo_4.png', 'assets/images/logo_5.png', 'assets/images/logo_6.png', ]; TextEditingController password = TextEditingController(); TextEditingController email = TextEditingController(); String platformname = ""; late FocusNode _emailFocusNode; late FocusNode _passwordFocusNode; bool _isTextFieldFocused = false; KeyboardVisibilityController _keyboardVisibilityController = KeyboardVisibilityController(); @override void initState() { super.initState(); Future.microtask(() { final prov = Provider.of(context, listen: false); if(Platform.isAndroid){ prov.initAndroidId(); }else if(Platform.isIOS){ prov.getDevId(); } }); tooltipcontroller = SuperTooltipController(); _scrollController = ScrollController(); _controller = AnimationController( vsync: this, duration: const Duration(seconds: 75), // Adjust speed of scroll )..addListener(() { _scrollController.jumpTo(_controller.value * 10000); if (_controller.value == 1.0) { _controller.repeat(); _scrollController.jumpTo(0); } }); _controller.repeat(); _emailFocusNode = FocusNode(); _passwordFocusNode = FocusNode(); if (!mounted) return; _emailFocusNode.addListener(() { setState(() { _isTextFieldFocused = _emailFocusNode.hasFocus || _passwordFocusNode.hasFocus; }); }); _passwordFocusNode.addListener(() { setState(() { _isTextFieldFocused = _emailFocusNode.hasFocus || _passwordFocusNode.hasFocus; }); }); _keyboardVisibilityController.onChange.listen((bool visible) { if (visible) { setState(() { _isTextFieldFocused = true; }); // print("Keyboard is visible${visibility}"); } else { setState(() { _isTextFieldFocused = false; }); // print("Keyboard is not visible${visibility}"); } }); } @override void dispose() { _controller.dispose(); _scrollController.dispose(); super.dispose(); } Future onBackPressed() async { return await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Are you sure?'), content: const Text('Do you want to exit the App'), actions: [ TextButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.white), overlayColor: MaterialStateProperty.all(Colors.white), ), onPressed: () => Navigator.of(context).pop(false), child: Text( "NO", style: TextStyle(fontWeight: FontWeight.w500), ), ), const SizedBox(height: 16), TextButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.white), overlayColor: MaterialStateProperty.all(Colors.white70), ), onPressed: () => SystemChannels.platform.invokeMethod( 'SystemNavigator.pop', ), child: Text( "YES", style: TextStyle(fontWeight: FontWeight.w500), ), ), ], elevation: 30.0, ), barrierDismissible: false, ) ?? false; } @override Widget build(BuildContext context) { var loginProv = Provider.of(context,listen: true); double screenWidth = MediaQuery.of(context).size.width; double screenHeight = MediaQuery.of(context).size.height; return WillPopScope( onWillPop: onBackPressed, child: Scaffold( resizeToAvoidBottomInset: true, backgroundColor: AppColors.scaffold_bg_color, body: KeyboardVisibilityProvider( controller: _keyboardVisibilityController, child: Stack( alignment: Alignment.center, children: [ // Background scrolling logos ListView.builder( controller: _scrollController, itemBuilder: (context, index) { int logoIndex = index % logos.length; return Padding( padding: const EdgeInsets.all(3.0), child: CustomGridRow(logos: logos, logoIndex: logoIndex), ); }, ), AnimatedPositioned( bottom: 0, left: 0, right: 0, duration: Duration(milliseconds: 300), child: Container( clipBehavior: Clip.antiAlias, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment(-0.00, -1.00), end: Alignment(0, 1), colors: [ Colors.white.withOpacity(0.0), // Fully transparent at the very top Colors.white.withOpacity(0.3), // Light fade-in Colors.white.withOpacity(0.6), // Mid fade Colors.white, // Solid white for the rest ], stops: [0.0, 0.05, 0.1, 0.15], ), ), child: SingleChildScrollView( child: Stack( alignment: Alignment.center, children: [ Container( alignment: Alignment.center, padding: EdgeInsets.symmetric( horizontal: 15, vertical: 10, ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ AnimatedContainer( duration: const Duration(milliseconds: 1200), curve: Curves.easeInOut, child: _isTextFieldFocused ? Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 1, child: SizedBox(width: 10), ), Expanded( flex: 2, child: Image.asset( "assets/images/gen_logo.png", ), ), const SizedBox(width: 10), Expanded( flex: 3, child: Image.asset("assets/images/gen_logo_grad.png"), ), Expanded( flex: 1, child: SizedBox(width: 10), ), ], ) : Column( children: [ Container( width: 180, height: 120, child: Image.asset( "assets/images/gen_logo.png", ), ), Image.asset("assets/images/gen_logo_grad.png",width: 150,), ], ), ), SizedBox(height: 10,), Text( "Login to enter", style: TextStyle( fontSize: 14, fontFamily: "JakartaMedium", color: AppColors.app_blue, ), ), Container( padding: EdgeInsets.only(left: 10,bottom: 5), alignment: Alignment.topLeft, child: Text( "Email ID", style: TextStyle( color: AppColors.semi_black, fontFamily: "JakartaMedium", fontSize: 14, ), ), ), Container( height: 48, alignment: Alignment.center, decoration: BoxDecoration( color: AppColors.text_field_color, borderRadius: BorderRadius.circular(14), border: _emailFocusNode.hasFocus?Border.all(color: AppColors.app_blue,width: 0.5):null ), // alignment: Alignment.center, margin: EdgeInsets.only(left: 5.0, right: 5.0), child: Padding( padding: const EdgeInsets.fromLTRB( 10.0, 0.0, 15, 0, ), child: TextField( controller: email, keyboardType: TextInputType.emailAddress, focusNode: _emailFocusNode, style: TextStyle( fontSize: 14 ), onChanged: (value) { loginProv.updateEmail(email.text); }, onTapOutside: (event) { // Handle onTapOutside FocusScope.of(context).unfocus(); }, decoration: InputDecoration( isDense: true, hintStyle: TextStyle( fontWeight: FontWeight.w400, fontSize: 14, color: Color(0xFF818181) ), //contentPadding: EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0), enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, hintText: 'Enter Your Email', ), ), ), ), if (loginProv.emailError != null) ...[ Container( alignment: Alignment.topLeft, margin: EdgeInsets.only( top: 2.5, bottom: 2.5, left: 25, ), child: Text( loginProv.emailError, textAlign: TextAlign.start, style: TextStyle(color: Colors.red), ), ), ] else ...[ SizedBox(height: 10.0), ], Container( padding: EdgeInsets.only(left: 10,bottom: 5), alignment: Alignment.topLeft, child: Text( "Password", style: TextStyle( color: AppColors.semi_black, fontFamily: "JakartaMedium", fontSize: 14, ), ), ), Container( height: 48, alignment: Alignment.center, decoration: BoxDecoration( color: AppColors.text_field_color, borderRadius: BorderRadius.circular(14), border: _passwordFocusNode.hasFocus?Border.all(color: AppColors.app_blue,width: 0.5):null ), // alignment: Alignment.center, margin: EdgeInsets.only(left: 5.0, right: 5.0), child: Padding( padding: const EdgeInsets.fromLTRB( 10.0, 0.0, 0, 0, ), child: TextField( controller: password, focusNode: _passwordFocusNode, obscureText: !loginProv.pwdVisible, keyboardType: TextInputType.visiblePassword, style: TextStyle( fontSize: 14, ), onChanged: (value) { loginProv.updatePassword(password.text); }, onEditingComplete: () { }, decoration: InputDecoration( contentPadding: EdgeInsets.fromLTRB( 0, 10, 0, 0, ), hintText: "Enter Password", suffixIcon: IconButton( icon: Icon( loginProv.pwdVisible ? CupertinoIcons.eye_solid : CupertinoIcons.eye_slash_fill, size: 30, ), onPressed: () { loginProv.visibility_ov(); }, ), hintStyle: TextStyle( fontSize: 14, color: Color(0xFF818181), fontWeight: FontWeight.w400, ), isDense: true, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, ), ), ), ), if (loginProv.passwordError != null) ...[ Container( alignment: Alignment.topLeft, margin: EdgeInsets.only( top: 2.5, bottom: 2.5, left: 25, ), child: Text( loginProv.passwordError, textAlign: TextAlign.start, style: TextStyle(color: Colors.red), ), ), ] else ...[ SizedBox(height: 25.0), ], Container( child: InkWell( onTap: () { // LoginApiFunction(); loginProv.LoginApiFunction(context, email.text, password.text); var f = FocusScope.of(context); if (!f.hasPrimaryFocus) { f.unfocus(); } // Navigator.push(context,MaterialPageRoute(builder: (context)=>Profile())); }, child: Container( alignment: Alignment.center, height: 45, width: screenWidth, margin: EdgeInsets.only( left: 5.0, right: 5.0, ), decoration: BoxDecoration( color: loginProv.isButtonEnabled?AppColors.app_blue:AppColors.button_disabled, //1487C9 borderRadius: BorderRadius.circular(15.0), ), child: Center( child: Text( "Login", textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontFamily: "JakartaRegular",), ), ), ), ), ), ], ), ), ], ), ), ), ), Positioned( top: 50, right: 20, child: InkResponse( child: GestureDetector( onTap: () async { await tooltipcontroller.showTooltip(); }, child: SuperTooltip( controller: tooltipcontroller, popupDirection: TooltipDirection.down, backgroundColor: Colors.white, borderColor: Colors.white, showCloseButton: true, left: 50, right: 30, barrierColor: Colors.transparent, arrowTipDistance: 20.0, minimumOutsideMargin: 120, arrowBaseWidth: 20.0, arrowLength: 20.0, borderWidth: 2.0, constraints: const BoxConstraints( minHeight: 0.0, maxHeight: 100, minWidth: 0.0, maxWidth: 100, ), touchThroughAreaShape: ClipAreaShape.rectangle, touchThroughAreaCornerRadius: 30, content: Container( height: 100, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text("Device ID", style: TextStyle( fontSize: 16, fontFamily: "JakartaMedium", color: AppColors.app_blue ),), SizedBox(height: 15,), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( height: 50, padding: EdgeInsets.symmetric(horizontal: 10,vertical: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(18), color: AppColors.text_field_color ), child: Row( children: [ Container( width: 180, height: 45, alignment: Alignment.center, margin: EdgeInsets.only(right: 5.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0)), child: Text( '${loginProv.deviceId}', style: TextStyle( fontSize: 16, color: AppColors.semi_black ), )), Container( child: InkWell( onTap: () async { Clipboard.setData(ClipboardData(text: loginProv.deviceId.trim())); toast(context, "Device ID has been copied!"); }, child: Icon( Icons.copy ), ), ), ], ), ), Spacer(), Container( width: 60, height: 50, decoration: BoxDecoration( color: AppColors.app_blue, borderRadius: BorderRadius.circular(18) ), child: InkWell( onTap: () { Share.share("${loginProv.deviceId}"); }, child: Icon( Icons.share_outlined, color: Colors.white, ), )), ], ), ], ), ), child: Align( alignment: Alignment.topRight, child: Container( width: 100, padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), decoration: BoxDecoration( color: AppColors.overlay_box_color, borderRadius: BorderRadius.circular(8), border: Border.all(color: AppColors.app_blue, width: 0.5), ), child: Center( child: Text( "Device ID", textAlign: TextAlign.center, style: TextStyle( color: AppColors.app_blue, fontSize: 14, ), ), ), ), ), ), ), ), ), ], ), ), ), ); } } class CustomGridRow extends StatelessWidget { final List logos; final int logoIndex; const CustomGridRow({ super.key, required this.logos, required this.logoIndex, }); @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ LogoWidget(imagePath: logos[logoIndex % logos.length]), LogoWidget(imagePath: logos[(logoIndex + 1) % logos.length]), LogoWidget(imagePath: logos[(logoIndex + 2) % logos.length]), LogoWidget(imagePath: logos[(logoIndex + 3) % logos.length]), ], ); } } class LogoWidget extends StatelessWidget { final String imagePath; const LogoWidget({super.key, required this.imagePath}); @override Widget build(BuildContext context) { return Container( width: MediaQuery.of(context).size.width/4.5, height: MediaQuery.of(context).size.width/4.5, decoration: BoxDecoration( image: DecorationImage(image: AssetImage(imagePath), fit: BoxFit.cover), ), ); } }