From 8a8dd6457dfefc57aa60b7c9345198a064bcf9be Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 19 Aug 2020 12:08:16 +0300 Subject: [PATCH] Finish login page --- lib/main.dart | 10 +- lib/pages/authentication/login_page.dart | 212 +++++++++++---- lib/widgets/input/text_field.dart | 331 +++++++++++++---------- 3 files changed, 364 insertions(+), 189 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index c93225c..9626777 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,10 +5,10 @@ import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; import 'config/size_config.dart'; -import 'core/service/authentication_service.dart'; import 'core/viewModels/project_view_model.dart'; import 'locator.dart'; -import 'pages/landing/landing_page.dart'; + + void main() { setupLocator(); @@ -56,6 +56,9 @@ class MyApp extends StatelessWidget { scaffoldBackgroundColor:Color.fromRGBO(239, 245, 245, 1) , hintColor: Colors.grey[400], disabledColor: Colors.grey[300], + bottomSheetTheme: BottomSheetThemeData( + backgroundColor: Color.fromRGBO(239, 245, 245, 1) + ), errorColor: Color.fromRGBO(235, 80, 60, 1.0), textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), textSelectionHandleColor: Color.fromRGBO(80, 100, 253, 1.0), @@ -63,9 +66,10 @@ class MyApp extends StatelessWidget { backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100].withOpacity(0.4), splashColor: Colors.transparent, - primaryColor: Colors.grey, + primaryColor: Color.fromRGBO(69, 183, 174, 1.0), cursorColor: Color.fromRGBO(78, 62, 253, 1.0), iconTheme: IconThemeData(), + dividerColor: Color.fromRGBO(112, 112, 112, 1.0), appBarTheme: AppBarTheme( color: Colors.grey, brightness: Brightness.light, diff --git a/lib/pages/authentication/login_page.dart b/lib/pages/authentication/login_page.dart index 0f860e7..f5dd638 100644 --- a/lib/pages/authentication/login_page.dart +++ b/lib/pages/authentication/login_page.dart @@ -2,9 +2,11 @@ import 'package:driverapp/app-icons/driver_app_icons.dart'; import 'package:driverapp/core/viewModels/authentication_view_model.dart'; import 'package:driverapp/pages/base/base_view.dart'; import 'package:driverapp/widgets/buttons/secondary_button.dart'; -import 'package:driverapp/widgets/others/app_scaffold_widget.dart'; +import 'package:driverapp/widgets/input/text_field.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:hexcolor/hexcolor.dart'; class LoginPage extends StatelessWidget { @override @@ -12,74 +14,192 @@ class LoginPage extends StatelessWidget { return AnimatedSwitcher( duration: Duration(microseconds: 350), child: BaseView( - builder: (_, model, widget) => AppScaffold( - baseViewModel: model, + builder: (_, model, widget) => Scaffold( + //baseViewModel: model, body: Center( child: Column( - + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ FractionallySizedBox( - widthFactor: 0.9, + widthFactor: 0.80, child: Column( - crossAxisAlignment: CrossAxisAlignment.center, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, + SizedBox( + height: 40, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon(DriverApp.logo, - size: 60, - color: Colors.red,), + Container( + child: Icon( + DriverApp.logo, + size: 70, + color: Theme.of(context).primaryColor, + ), + margin: EdgeInsets.only( + right: + MediaQuery.of(context).size.width * 0.15), + ), ], ), - Column(), - new Container( - height: 22.28, - width: 139.13, - decoration: BoxDecoration( - color: Color(0xffffffff), - border: Border.all( - width: 1.00, - color: Color(0xff707070), + SizedBox( + height: 20, + ), + Column( + children: [ + Text( + "Driver", + style: TextStyle( + fontSize: 50, fontWeight: FontWeight.bold), + ), + Text( + "Delivery", + style: TextStyle(fontSize: 36, letterSpacing: 1), + ), + Text( + "APP", + style: TextStyle( + fontSize: 33, + letterSpacing: 33, + fontWeight: FontWeight.w400), ), - borderRadius: BorderRadius.circular(6.00), - ), + ], + ), + SizedBox( + height: 30, ), - Container( - height: 22.28, - width: 139.13, - decoration: BoxDecoration( - color: Color(0xffffffff), - border: Border.all( - width: 1.00, - color: Color(0xff707070), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircleContainer( + child: Text( + "English", + style: TextStyle( + fontSize: 12, color: Colors.white), + ), + color: Theme.of(context).primaryColor, borderWidth: 0,borderColor: Colors.transparent,), + SizedBox( + width: 20, ), - borderRadius: BorderRadius.circular(6.00), - ), + CircleContainer( + child: Text( + "Arabic", + style: TextStyle( + fontSize: 12, color: Colors.black), + ), + color: Colors.transparent, borderColor: Theme.of(context).primaryColor,borderWidth: 3,), + ], + ), + SizedBox( + height: 10, ), - new Container( - height: 22.28, - width: 139.13, - decoration: BoxDecoration( - color: Color(0xffffffff), - border: Border.all( - width: 1.00, - color: Color(0xff707070), + Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "Please insert username and password to login", + style: TextStyle( + fontSize: 13, color: Colors.grey), + ), + SizedBox( + height: 10, + ) + ], + ), + ), + SizedBox( + height: 10, ), - borderRadius: BorderRadius.circular(6.00), - ), - ) + Container( + child: TextFields( + onChanged: (value) => {}, + hintText: "User Name", + ), + ), + SizedBox( + height: 20, + ), + Container( + child: TextFields( + borderRadiusValue: 6, + onChanged: (value) => {}, + hintText: "Password", + ), + ), + SizedBox( + height: 25, + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "Forgot Password?", + style: TextStyle( + fontSize: 14, + color: Theme.of(context).primaryColor), + ), + ], + ), + ], + ), ], ), ), - FractionallySizedBox( - widthFactor: 0.90, - child: SecondaryButton(label: "DFDf"), + SizedBox( + height: 20, + ), + SizedBox( + height: 10, ) ], ), ), + bottomSheet: Container( + margin: EdgeInsets.all(10), + height: MediaQuery.of(context).size.height * 0.12, + child: Column( + children: [ + SecondaryButton(label: "Login"), + SizedBox( + height: 30, + ) + ], + )), ), ), ); } } + +class CircleContainer extends StatelessWidget { + const CircleContainer( + {this.child, + this.color = Colors.white, + this.borderColor, + this.borderWidth = 2.0}); + + final Widget child; + final Color color; + final Color borderColor; + final double borderWidth; + + @override + Widget build(BuildContext context) { + return Container( + child: Center(child: child), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: color, + border: Border.all( + color: borderColor ?? Hexcolor("#707070"), + width: borderWidth)), + height: 60, + width: 60, + ); + } +} diff --git a/lib/widgets/input/text_field.dart b/lib/widgets/input/text_field.dart index 900c340..12b0adc 100644 --- a/lib/widgets/input/text_field.dart +++ b/lib/widgets/input/text_field.dart @@ -39,38 +39,44 @@ class NumberTextInputFormatter extends TextInputFormatter { final _mobileFormatter = NumberTextInputFormatter(); class TextFields extends StatefulWidget { - TextFields( - {Key key, - this.type, - this.hintText, - this.suffixIcon, - this.autoFocus, - this.onChanged, - this.initialValue, - this.minLines, - this.maxLines, - this.inputFormatters, - this.padding, - this.focus = false, - this.maxLengthEnforced = true, - this.suffixIconColor, - this.inputAction, - this.onSubmit, - this.keepPadding = true, - this.textCapitalization = TextCapitalization.none, - this.controller, - this.keyboardType, - this.validator, - this.borderOnlyError = false, - this.onSaved, - this.onSuffixTap, - this.readOnly: false, - this.maxLength, - this.prefixIcon, - this.bare = false, - this.fontSize = 16.0, - this.fontWeight = FontWeight.w700, - this.autoValidate = false}) + TextFields({Key key, + this.type, + this.hintText, + this.suffixIcon, + this.autoFocus, + this.onChanged, + this.initialValue, + this.minLines, + this.maxLines, + this.inputFormatters, + this.padding, + this.focus = false, + this.maxLengthEnforced = true, + this.suffixIconColor, + this.inputAction, + this.onSubmit, + this.keepPadding = true, + this.textCapitalization = TextCapitalization.none, + this.onTap, + this.controller, + this.keyboardType, + this.validator, + this.borderOnlyError = false, + this.onSaved, + this.onSuffixTap, + this.readOnly: false, + this.maxLength, + this.prefixIcon, + this.bare = false, + this.fontSize = 14.0, + this.color = Colors.black, + this.fontWeight = FontWeight.w600, + this.autoValidate = false, + this.borderRadiusValue = 8.0, + this.borderWidth = 1.5, + this.fieldTextColor, + this.textAlign = TextAlign.start, + this.borderRadius}) : super(key: key); final String hintText; @@ -80,6 +86,7 @@ class TextFields extends StatefulWidget { final IconData suffixIcon; final Color suffixIconColor; final IconData prefixIcon; + final VoidCallback onTap; final TextEditingController controller; final TextInputType keyboardType; final FormFieldValidator validator; @@ -96,6 +103,7 @@ class TextFields extends StatefulWidget { final TextInputAction inputAction; final double fontSize; final FontWeight fontWeight; + final Color color; final bool keepPadding; final TextCapitalization textCapitalization; final List inputFormatters; @@ -103,6 +111,11 @@ class TextFields extends StatefulWidget { final EdgeInsets padding; final bool focus; final bool borderOnlyError; + final double borderRadiusValue; + final BorderRadius borderRadius; + final double borderWidth; + final Color fieldTextColor; + final TextAlign textAlign; @override _TextFieldsState createState() => _TextFieldsState(); @@ -138,43 +151,46 @@ class _TextFieldsState extends State { Widget _buildSuffixIcon() { switch (widget.type) { case "password": - return Padding( - padding: const EdgeInsets.only(right: 8.0), - child: view - ? InkWell( + { + return Padding( + padding: const EdgeInsets.only(right: 8.0), + child: view + ? InkWell( onTap: () { - this.setState( - () { - view = false; - }, - ); + this.setState(() { + view = false; + }); }, - child: Icon( - EvaIcons.eye, - size: 24.0, - color: Color.fromRGBO(78, 62, 253, 1.0), - ), - ) - : InkWell( + child: Icon(EvaIcons.eye, + size: 24.0, color: Theme + .of(context) + .primaryColor)) + : InkWell( onTap: () { this.setState(() { view = true; }); }, child: Icon(EvaIcons.eyeOff, - size: 24.0, color: Colors.grey[500]), - ), - ); + size: 24.0, color: Colors.grey[500]))); + } + case "hourly": + return Align( + alignment: Alignment.centerRight, + child: Text( + '/ hr ', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700), + )); + break; default: if (widget.suffixIcon != null) return InkWell( - onTap: widget.onSuffixTap, - child: Icon(widget.suffixIcon, - size: 22.0, - color: widget.suffixIconColor != null - ? widget.suffixIconColor - : Colors.grey[500]), - ); + onTap: widget.onSuffixTap, + child: Icon(widget.suffixIcon, + size: 22.0, + color: widget.suffixIconColor != null + ? widget.suffixIconColor + : Colors.grey[500])); else return null; } @@ -196,22 +212,26 @@ class _TextFieldsState extends State { decoration: widget.bare ? null : BoxDecoration(boxShadow: [ - BoxShadow( - color: Color.fromRGBO(110, 68, 80, focus ? 0.20 : 0), - offset: Offset(0.0, 13.0), - blurRadius: focus ? 34.0 : 12.0) - ]), + BoxShadow( + color: Color.fromRGBO(70, 68, 167, focus ? 0.20 : 0), + offset: Offset(0.0, 13.0), + blurRadius: focus ? 34.0 : 12.0) + ]), child: TextFormField( - keyboardAppearance: Theme.of(context).brightness, + keyboardAppearance: Theme + .of(context) + .brightness, scrollPhysics: BouncingScrollPhysics(), autovalidate: widget.autoValidate, + onTap: widget.onTap, + textAlign: widget.textAlign, textCapitalization: widget.textCapitalization, onFieldSubmitted: widget.inputAction == TextInputAction.next ? (widget.onSubmit != null - ? widget.onSubmit - : (val) { - _focusNode.nextFocus(); - }) + ? widget.onSubmit + : (val) { + _focusNode.nextFocus(); + }) : widget.onSubmit, textInputAction: widget.inputAction, minLines: widget.minLines ?? 1, @@ -228,87 +248,118 @@ class _TextFieldsState extends State { autofocus: widget.autoFocus ?? false, validator: widget.validator, onSaved: widget.onSaved, - style: Theme.of(context) + style: Theme + .of(context) .textTheme .body2 - .copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + .copyWith( + fontSize: widget.fontSize, + fontWeight: widget.fontWeight, + color: widget.color), inputFormatters: widget.keyboardType == TextInputType.phone ? [ - WhitelistingTextInputFormatter.digitsOnly, - _mobileFormatter, - ] + WhitelistingTextInputFormatter.digitsOnly, + _mobileFormatter, + ] : widget.inputFormatters, decoration: InputDecoration( - counterText: "", - hintText: widget.hintText, - hintStyle: TextStyle( - fontSize: widget.fontSize, - fontWeight: widget.fontWeight, - color: Theme.of(context).hintColor), - contentPadding: widget.padding != null - ? widget.padding - : EdgeInsets.symmetric( - vertical: (widget.bare && !widget.keepPadding) ? 0.0 : 10.0, - horizontal: 16.0), - filled: true, - fillColor: widget.bare - ? Colors.transparent - : Theme.of(context).backgroundColor, - suffixIcon: _buildSuffixIcon(), - prefixIcon: widget.type != "search" - ? widget.prefixIcon != null - ? Padding( - padding: EdgeInsets.only( - left: 28.0, top: 14.0, bottom: 14.0, right: 0), - child: Text( - "\$", - style: TextStyle( - fontSize: 14, fontWeight: FontWeight.w800), - ), - ) - : null - : Icon(EvaIcons.search, size: 20.0, color: Colors.grey[500]), - errorStyle: TextStyle( - fontSize: 14.0, - fontWeight: widget.fontWeight, - height: widget.borderOnlyError ? 0.0 : null), - errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(widget.bare ? 0.0 : 0.5), - width: 2.0), - borderRadius: BorderRadius.circular(widget.bare ? 0.0 : 8.0)), - focusedErrorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(widget.bare ? 0.0 : 0.5), - width: 2.0), - borderRadius: BorderRadius.circular(widget.bare ? 0.0 : 8.0)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .dividerColor - .withOpacity(widget.bare ? 0.0 : 1.0), - width: 2.0), - borderRadius: BorderRadius.circular(widget.bare ? 0.0 : 8.0)), - disabledBorder: OutlineInputBorder( + counterText: "", + hintText: widget.hintText, + hintStyle: TextStyle( + fontSize: widget.fontSize, + fontWeight: widget.fontWeight, + color: Theme + .of(context) + .hintColor), + contentPadding: widget.padding != null + ? widget.padding + : EdgeInsets.symmetric( + vertical: (widget.bare && !widget.keepPadding) ? 0.0 : 10.0, + horizontal: 16.0), + filled: true, + fillColor: widget.bare + ? Colors.transparent + : widget.fieldTextColor != null + ? widget.fieldTextColor + : Theme + .of(context) + .backgroundColor, + suffixIcon: _buildSuffixIcon(), + prefixIcon: widget.type != "search" + ? widget.prefixIcon != null + ? Padding( + padding: EdgeInsets.only( + left: 28.0, top: 14.0, bottom: 14.0, right: 0), + child: Text( + "\$", + style: TextStyle( + fontSize: 14, fontWeight: FontWeight.w800), + ), + ) + : null + : Icon(EvaIcons.search, size: 20.0, color: Colors.grey[500]), + errorStyle: TextStyle( + fontSize: 14.0, + fontWeight: widget.fontWeight, + height: widget.borderOnlyError ? 0.0 : null), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme + .of(context) + .errorColor + .withOpacity(widget.bare ? 0.0 : 0.5), + width: widget.borderWidth), + borderRadius: widget.bare + ? BorderRadius.circular(0.0) + : widget.borderRadius != null + ? widget.borderRadius + : BorderRadius.circular(widget.borderRadiusValue)), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme + .of(context) + .errorColor + .withOpacity(widget.bare ? 0.0 : 0.5), + width: widget.borderWidth), + borderRadius: widget.bare + ? BorderRadius.circular(0.0) + : widget.borderRadius != null + ? widget.borderRadius + : BorderRadius.circular(widget.borderRadiusValue)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme + .of(context) + .dividerColor + .withOpacity(widget.bare ? 0.0 : 1.0), + width: widget.borderWidth), + borderRadius: widget.bare + ? BorderRadius.circular(0.0) + : widget.borderRadius != null + ? widget.borderRadius + : BorderRadius.circular(widget.borderRadiusValue)), + disabledBorder: + OutlineInputBorder(borderSide: BorderSide(color: Theme + .of(context) + .dividerColor + .withOpacity(widget.bare ? 0.0 : 1.0), + width: widget.borderWidth), + borderRadius: widget.bare ? BorderRadius.circular(0.0) : widget + .borderRadius != null ? widget.borderRadius : BorderRadius + .circular(widget.borderRadiusValue)), + enabledBorder: OutlineInputBorder( borderSide: BorderSide( - color: Theme.of(context) + color: Theme + .of(context) .dividerColor .withOpacity(widget.bare ? 0.0 : 1.0), - width: 2.0), - borderRadius: BorderRadius.circular(widget.bare ? 0.0 : 8.0)), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Theme.of(context) - .dividerColor - .withOpacity(widget.bare ? 0.0 : 1.0), - width: 2.0), - borderRadius: BorderRadius.circular(widget.bare ? 0.0 : 8.0), - ), - ), + width: widget.borderWidth), + borderRadius: widget.bare + ? BorderRadius.circular(0.0) + : widget.borderRadius != null + ? widget.borderRadius + : BorderRadius.circular(widget.borderRadiusValue), + )), ), )); }