From 05ab4c48117055a6211149b87b33b118fc8c1ca0 Mon Sep 17 00:00:00 2001 From: Kelvin Samuel Date: Sun, 1 May 2022 00:04:01 +0700 Subject: [PATCH] Change Login page UI, add icon, add feature remember me, forgot pass, sign up --- lib/components/login_form.dart | 264 ++++++++++++++++++++++++++++----- lib/components/menu.dart | 6 +- lib/utils/utils.dart | 25 +++- test/widget_test.dart | 30 ++++ 4 files changed, 289 insertions(+), 36 deletions(-) create mode 100644 test/widget_test.dart diff --git a/lib/components/login_form.dart b/lib/components/login_form.dart index 4e9e8ce..e9e32c0 100644 --- a/lib/components/login_form.dart +++ b/lib/components/login_form.dart @@ -1,8 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_launcher_icons_maker/xml_templates.dart'; import 'package:lottie/lottie.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:nekoya_flutter/api/api.dart'; import 'package:nekoya_flutter/components/login_error.dart'; +import 'package:nekoya_flutter/utils/utils.dart'; class LoginForm extends StatefulWidget { const LoginForm({Key? key}) : super(key: key); @@ -14,47 +17,241 @@ class LoginForm extends StatefulWidget { final _formKey = GlobalKey(); class LoginFormState extends State { + bool _rememberMe = false; + + Widget _buildEmailTF() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Email', + style: kLabelStyle, + ), + SizedBox(height: 10.0), + Container( + alignment: Alignment.centerLeft, + decoration: kBoxDecorationStyle, + height: 60.0, + child: TextField( + keyboardType: TextInputType.emailAddress, + style: TextStyle( + color: Colors.white, + fontFamily: 'OpenSans', + ), + decoration: InputDecoration( + border: InputBorder.none, + contentPadding: EdgeInsets.only(top: 14.0), + prefixIcon: Icon( + Icons.email, + color: Colors.white, + ), + hintText: 'Enter yout Email', + hintStyle: kHintTextStyle, + ), + )) + ], + ); + } + + Widget _buildPasswordTF() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Password', + style: kLabelStyle, + ), + SizedBox(height: 10.0), + Container( + alignment: Alignment.centerLeft, + decoration: kBoxDecorationStyle, + height: 60.0, + child: TextField( + obscureText: true, + style: TextStyle( + color: Colors.white, + fontFamily: 'OpenSans', + ), + decoration: InputDecoration( + border: InputBorder.none, + contentPadding: EdgeInsets.only(top: 14.0), + prefixIcon: Icon( + Icons.lock, + color: Colors.white, + ), + hintText: 'Enter yout Password', + hintStyle: kHintTextStyle, + ), + )) + ], + ); + } + + Widget _buildForgotPasswordBtn() { + return Container( + alignment: Alignment.centerRight, + child: FlatButton( + onPressed: () => print('Forgot Password Button Pressed'), + padding: EdgeInsets.only(right: 0.0), + child: Text( + 'Forgot Password?', + style: kLabelStyle, + ), + )); + } + + Widget _buildRememberMeCheckBox() { + return Container( + height: 13.0, + child: Row( + children: [ + Theme( + data: ThemeData(unselectedWidgetColor: Colors.white), + child: Checkbox( + value: _rememberMe, + checkColor: Colors.green, + activeColor: Colors.white, + onChanged: (value) { + setState(() { + _rememberMe = value!; + }); + }, + ), + ), + Text( + 'Remember me', + style: kLabelStyle, + ) + ], + ), + ); + } + + Widget _buildLoginBtn() { + return Container( + padding: EdgeInsets.symmetric(vertical: 25.0), + width: double.infinity, + child: RaisedButton( + elevation: 5.0, + onPressed: () => print('Login Button Pressed'), + padding: EdgeInsets.all(15.0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + color: const Color(0xff8B0000), + child: Text( + 'LOGIN', + style: TextStyle( + color: Colors.white, + letterSpacing: 1.5, + fontSize: 18.0, + fontWeight: FontWeight.bold, + fontFamily: 'OpenSans', + ), + ), + ), + ); + } + + Widget _buildSignupBtn() { + return GestureDetector( + onTap: () => print('Sign Up Button Pressed'), + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'Don\'t have an Account? ', + style: TextStyle( + color: Colors.white, + fontSize: 18.0, + fontWeight: FontWeight.w400, + ), + ), + TextSpan( + text: 'Sign Up', + style: TextStyle( + color: Colors.white, + fontSize: 18.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ); + } + @override Widget build(BuildContext context) { return SafeArea( child: Container( - margin: const EdgeInsets.fromLTRB(10, 15, 10, 5), + margin: const EdgeInsets.fromLTRB(10, 10, 10, 5), child: Card( - color: const Color(0xff212226), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15), - ), - child: SingleChildScrollView( - child: Container( - transform: Matrix4.translationValues(0, -35, 0), - padding: const EdgeInsets.fromLTRB(10, 20, 10, 0), - height: MediaQuery.of(context).size.height, - width: double.infinity, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Lottie.asset( - "assets/lottieanims/login_form.json", - frameRate: FrameRate.max, - alignment: Alignment.center, - fit: BoxFit.fitHeight, - height: 250, - ), - ], - ), - Padding( + color: const Color(0xff212226), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + child: SingleChildScrollView( + child: Container( + transform: Matrix4.translationValues(0, -35, 0), + padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), + height: MediaQuery.of(context).size.height, + width: double.infinity, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Lottie.asset( + "assets/lottieanims/login_form.json", + frameRate: FrameRate.max, + alignment: Alignment.center, + fit: BoxFit.fitHeight, + height: 250, + ), + SizedBox(height: 10.0), + _buildEmailTF(), + SizedBox( + height: 30.0, + ), + _buildPasswordTF(), + _buildForgotPasswordBtn(), + _buildRememberMeCheckBox(), + _buildLoginBtn(), + _buildSignupBtn(), + ], + ), + ), + )), + ), + ); + } +} + + /* Padding( padding: const EdgeInsets.symmetric(horizontal: 25), child: FormBuilder( key: _formKey, child: Column( children: [ - makeInput(label: "Email"), - makeInput(label: "Password", obscureText: true) + TextField( + style: TextStyle( + fontSize: 20, + fontStyle: FontStyle.italic, + color: Colors.white, + ), + decoration: new InputDecoration( + hintText: "Enter your email", + labelText: "Email", + prefixIcon: Icon(Icons.email), + labelStyle: new TextStyle( + color: const Color(0xFFFFFFFF)), + border: new UnderlineInputBorder( + borderSide: + new BorderSide(color: Colors.red))), + ), + makeInput( + label: "Password", + obscureText: true, + ) ], ), ), @@ -131,9 +328,9 @@ class LoginFormState extends State { ), ); } -} + */ -Widget makeInput({label, obscureText = false}) { +/* Widget makeInput({label, obscureText = false}) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -204,3 +401,4 @@ showAlertDialog(BuildContext context) { }, ); } + */ \ No newline at end of file diff --git a/lib/components/menu.dart b/lib/components/menu.dart index 9db45f9..78d437f 100644 --- a/lib/components/menu.dart +++ b/lib/components/menu.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:nekoya_flutter/screens/login.dart'; import 'dart:math' as math; import 'package:nekoya_flutter/screens/products.dart'; import 'package:nekoya_flutter/screens/payment.dart'; import 'package:nekoya_flutter/screens/cart.dart'; +import 'package:nekoya_flutter/screens/register.dart'; import 'package:nekoya_flutter/screens/sessions.dart'; import 'package:nekoya_flutter/screens/transactions.dart'; @@ -59,7 +61,7 @@ class _MenuState extends State { setState(() { _selectedIndex = index; if (index == 0) { - _selectedWidget = const Sessions(); + _selectedWidget = const Login(); } else if (index == 1) { _selectedWidget = const Payment(); } else if (index == 2) { @@ -67,7 +69,7 @@ class _MenuState extends State { } else if (index == 3) { _selectedWidget = const Cart(); } else if (index == 4) { - _selectedWidget = const Transactions(); + _selectedWidget = const Register(); } }); } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index d0765bc..3f32cf8 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -6,4 +6,27 @@ class HideScrollGlow extends ScrollBehavior { BuildContext context, Widget child, ScrollableDetails details) { return child; } -} \ No newline at end of file +} + +final kHintTextStyle = TextStyle( + color: Colors.white54, + fontFamily: 'OpenSans', +); + +final kLabelStyle = TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontFamily: 'OpenSans', +); + +final kBoxDecorationStyle = BoxDecoration( + color: Color(0xFF6CA8F1), + borderRadius: BorderRadius.circular(10.0), + boxShadow: [ + BoxShadow( + color: Colors.black12, + blurRadius: 6.0, + offset: Offset(0, 2), + ), + ], +); diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..c572f1c --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:app/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}