Change Login page UI, add icon, add feature remember me, forgot pass, sign up

This commit is contained in:
Kelvin Samuel 2022-05-01 00:04:01 +07:00
parent c296201017
commit 05ab4c4811
4 changed files with 289 additions and 36 deletions

View file

@ -1,8 +1,11 @@
import 'package:flutter/material.dart'; 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:lottie/lottie.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:nekoya_flutter/api/api.dart'; import 'package:nekoya_flutter/api/api.dart';
import 'package:nekoya_flutter/components/login_error.dart'; import 'package:nekoya_flutter/components/login_error.dart';
import 'package:nekoya_flutter/utils/utils.dart';
class LoginForm extends StatefulWidget { class LoginForm extends StatefulWidget {
const LoginForm({Key? key}) : super(key: key); const LoginForm({Key? key}) : super(key: key);
@ -14,11 +17,175 @@ class LoginForm extends StatefulWidget {
final _formKey = GlobalKey<FormBuilderState>(); final _formKey = GlobalKey<FormBuilderState>();
class LoginFormState extends State<LoginForm> { class LoginFormState extends State<LoginForm> {
bool _rememberMe = false;
Widget _buildEmailTF() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
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: <Widget>[
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: <Widget>[
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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SafeArea( return SafeArea(
child: Container( child: Container(
margin: const EdgeInsets.fromLTRB(10, 15, 10, 5), margin: const EdgeInsets.fromLTRB(10, 10, 10, 5),
child: Card( child: Card(
color: const Color(0xff212226), color: const Color(0xff212226),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@ -27,16 +194,11 @@ class LoginFormState extends State<LoginForm> {
child: SingleChildScrollView( child: SingleChildScrollView(
child: Container( child: Container(
transform: Matrix4.translationValues(0, -35, 0), transform: Matrix4.translationValues(0, -35, 0),
padding: const EdgeInsets.fromLTRB(10, 20, 10, 0), padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
height: MediaQuery.of(context).size.height, height: MediaQuery.of(context).size.height,
width: double.infinity, width: double.infinity,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
Lottie.asset( Lottie.asset(
"assets/lottieanims/login_form.json", "assets/lottieanims/login_form.json",
@ -45,16 +207,51 @@ class LoginFormState extends State<LoginForm> {
fit: BoxFit.fitHeight, fit: BoxFit.fitHeight,
height: 250, height: 250,
), ),
SizedBox(height: 10.0),
_buildEmailTF(),
SizedBox(
height: 30.0,
),
_buildPasswordTF(),
_buildForgotPasswordBtn(),
_buildRememberMeCheckBox(),
_buildLoginBtn(),
_buildSignupBtn(),
], ],
), ),
Padding( ),
)),
),
);
}
}
/* Padding(
padding: const EdgeInsets.symmetric(horizontal: 25), padding: const EdgeInsets.symmetric(horizontal: 25),
child: FormBuilder( child: FormBuilder(
key: _formKey, key: _formKey,
child: Column( child: Column(
children: [ children: [
makeInput(label: "Email"), TextField(
makeInput(label: "Password", obscureText: true) 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<LoginForm> {
), ),
); );
} }
} */
Widget makeInput({label, obscureText = false}) { /* Widget makeInput({label, obscureText = false}) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -204,3 +401,4 @@ showAlertDialog(BuildContext context) {
}, },
); );
} }
*/

View file

@ -1,9 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:nekoya_flutter/screens/login.dart';
import 'dart:math' as math; import 'dart:math' as math;
import 'package:nekoya_flutter/screens/products.dart'; import 'package:nekoya_flutter/screens/products.dart';
import 'package:nekoya_flutter/screens/payment.dart'; import 'package:nekoya_flutter/screens/payment.dart';
import 'package:nekoya_flutter/screens/cart.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/sessions.dart';
import 'package:nekoya_flutter/screens/transactions.dart'; import 'package:nekoya_flutter/screens/transactions.dart';
@ -59,7 +61,7 @@ class _MenuState extends State<Menu> {
setState(() { setState(() {
_selectedIndex = index; _selectedIndex = index;
if (index == 0) { if (index == 0) {
_selectedWidget = const Sessions(); _selectedWidget = const Login();
} else if (index == 1) { } else if (index == 1) {
_selectedWidget = const Payment(); _selectedWidget = const Payment();
} else if (index == 2) { } else if (index == 2) {
@ -67,7 +69,7 @@ class _MenuState extends State<Menu> {
} else if (index == 3) { } else if (index == 3) {
_selectedWidget = const Cart(); _selectedWidget = const Cart();
} else if (index == 4) { } else if (index == 4) {
_selectedWidget = const Transactions(); _selectedWidget = const Register();
} }
}); });
} }

View file

@ -7,3 +7,26 @@ class HideScrollGlow extends ScrollBehavior {
return child; return child;
} }
} }
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),
),
],
);

30
test/widget_test.dart Normal file
View file

@ -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);
});
}