import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart'; import '../../about/external/initial/LoginData.dart'; import '../../about/internal/application/NavigatorType.dart'; import '../../about/internal/application/TextType.dart'; import '../../about/internal/application/UserDetails.dart'; import '../../configs/Navigator.dart'; import '../../designs/Responsive.dart'; import '../../designs/buttons/Buttons.dart'; import '../../designs/input/InputFields.dart'; import '../../designs/text/Text.dart'; import '../../utils/Colors.dart'; import '../../utils/Validators.dart'; import '../home/Home.dart'; import 'ConnectLogin.dart'; import 'Login.dart'; import 'ViewLogin.dart'; class LoginState extends State implements ConnectLogin { ViewLogin? _model; final GlobalKey _formKey = GlobalKey(); final TextEditingController _username = TextEditingController(); final TextEditingController _password = TextEditingController(); bool _obscured = true; @override Widget build(BuildContext context) { return ViewModelBuilder.reactive( viewModelBuilder: () => ViewLogin(context, this), onViewModelReady: (viewModel) { _model = viewModel; _initiate(); }, builder: (context, viewModel, child) => Scaffold( backgroundColor: colorPrimaryDark, body: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return Responsive( mobile: _mobileView(constraints), tablet: _mobileView(constraints), desktop: _mobileView(constraints), ); }, ), ), ); } void _initiate() {} void _onToggleObscured() { setState(() { _obscured = !_obscured; }); } void _onSignIn() { if (_formKey.currentState?.validate() != true) { return; } _model?.login(LoginData( username: _username.text.trim(), password: _password.text, )); } Widget _mobileView(BoxConstraints constraints) { return Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SafeArea( bottom: false, child: Padding( padding: const EdgeInsets.fromLTRB(28, 24, 28, 32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ text("GROUNDED", 10, TextType.Bold, color: colorWhite.withValues(alpha: 0.45), letterSpacing: 2.0), const SizedBox(height: 22), text("Welcome back.", 36, TextType.Light, color: colorWhite, height: 1.1), const SizedBox(height: 10), text( "Your record has been waiting exactly where you left it.", 14, TextType.Regular, color: colorWhite.withValues(alpha: 0.55), height: 1.5, ), ], ), ), ), Expanded( child: Container( decoration: BoxDecoration( color: colorPrimaryLight, borderRadius: const BorderRadius.only( topLeft: Radius.circular(28), topRight: Radius.circular(28), ), ), clipBehavior: Clip.antiAlias, child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(24, 32, 24, 32), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ inputField( "Username", _username, hint: "The one you signed up with", validator: Validators.username, keyboard: TextInputType.emailAddress, icon: CupertinoIcons.person, ), const SizedBox(height: 20), inputField( "Password", _password, hint: "Your password", validator: Validators.password, obscure: _obscured, icon: CupertinoIcons.lock, ), const SizedBox(height: 8), Align( alignment: Alignment.centerRight, child: textButton( _obscured ? "Show password" : "Hide password", _onToggleObscured, textSize: 12, ), ), const SizedBox(height: 20), roundedCornerButton( "Sign in", _onSignIn, icon: CupertinoIcons.arrow_right, ), const SizedBox(height: 24), Center( child: text( "Nothing here judges you for being away.", 12, TextType.Regular, color: colorGrey2, align: TextAlign.center, ), ), ], ), ), ), ), ), ], ); } @override void onLoggedIn(UserDetails details) { GroundedNavigation() .navigateToPage(NavigatorType.makeNewMain, const Home(), context); } @override void dispose() { _username.dispose(); _password.dispose(); super.dispose(); } }